Commit Graph

902 Commits

Author SHA1 Message Date
timeless
a1cb3173a2 py3: convert to next() function
next(..) was introduced in py2.6 and .next() is not available in py3

https://docs.python.org/2/library/functions.html#next
2016-05-16 21:30:53 +00:00
Yuya Nishihara
3f981af86b templater: separate function to create templater from map file (API)
New frommapfile() function will make it clear when template aliases will be
loaded. They should be applied to command arguments and templates in hgrc,
but not to map files. Otherwise, our stock styles and web templates
(i.e map-file templates) could be modified unintentionally.

Future patches will add "aliases" argument to __init__(), but not to
frommapfile().
2016-04-03 23:26:48 +09:00
timeless
109fcbc79e pycompat: switch to util.urlreq/util.urlerr for py3 compat 2016-04-06 23:22:12 +00:00
timeless
f77cdcd3b1 pycompat: switch to util.stringio for py3 compat 2016-04-10 20:55:37 +00:00
Anton Shestakov
9f3a77930a hgweb: generate last change date for an empty atom-bookmarks feed (issue5022)
RFC 4287 states that atom feeds must have an <updated> element, so let's add
one even when repo doesn't have a single bookmark.
2016-03-31 15:37:21 +08:00
Anton Shestakov
d9e41fcffc hgweb: sort bookmarks in revlog order of their nodes
Changes, branches and tags are already in revlog order on /summary, /branches
and /tags, let's now make bookmarks be sorted by the same principle. It's more
helpful to show more "recent" bookmarks on top. This will affect /bookmarks
page in all styles, including atom, rss and raw, and also /summary page.

Bookmarks are sorted using a (revision number, bookmark name) tuple.
2016-03-31 15:22:06 +08:00
Anton Shestakov
0741a98a71 hgweb: sort bookmarks early
Let's do the same thing that /tags page does. It gets sorted tags and then if
it needs the latest only, it just slices the first item from the list. Since
it's a slice and not a min(), it doesn't throw an exception if the list is
empty. This fixes HTTP 500 error from issue5022.
2016-03-31 14:23:27 +08:00
Anton Shestakov
e81bf97ae9 hgweb: add parents to json-log (issue5074)
Entries prepared in webutil.changelistentry() skip showing parents in the
trivial case when there's only one parent and it's the previous revision. This
doesn't work well for the json-log template, which is supposed to just dump raw
data in an easy-to-parse format, so let's provide all parents as another
keyword: allparents.

Using a lambda function here means that the performance of templates that don't
use allparents won't be affected (see 88bd6697bfad).
2016-03-31 18:09:09 +08:00
Augie Fackler
b3f8347d29 http: support sending hgargs via POST body instead of in GET or headers
narrowhg (for its narrow spec) and remotefilelog (for its large batch
requests) would like to be able to make requests with argument sets so
absurdly large that they blow out total request size limit on some
http servers. As a workaround, support stuffing args at the start
of the POST body.

We will probably want to leave this behavior off by default in servers
forever, because it makes the old "POSTs are only for writes"
assumption wrong, which might break some of the simpler authentication
configurations.
2016-03-11 11:37:00 -05:00
Yuya Nishihara
2e33bbee20 templatefilters: make json filter be byte-transparent (BC) (issue4926)
This is necessary to preserve filename encoding over JSON. Instead, this
patch inserts "|utf8" where non-ascii local-encoding texts can be passed
to "|json".

See also the commit that introduced "utf8" filter.
2015-12-27 17:59:57 +09:00
Yuya Nishihara
bd35a9a988 hgweb: add option to convert encoding of graphdata()
Because future patches will change "|json" filter to handle input bytes
transparently, i.e. use UTF-8b encoding, "{jsdata}" must keep data in UTF-8
bytes, whereas "{nodes}" are text.

This patch inserts encodestr() where localstr is likely to survive.
2016-01-04 23:05:09 +09:00
Yuya Nishihara
0633dff1e2 hgweb: remove unused argument from graphdata() factory
As graphdata() is wrapped by lambda, there's no reason to pass unused
arguments to it.
2016-01-04 22:55:05 +09:00
Gregory Szorc
a3e59a30b6 hgweb: support rendering a sub-topic
If the requested topic contains a "." we assume a sub-topic is
requested and display it.
2015-12-30 17:15:10 -07:00
Gregory Szorc
a320e743a7 hgweb: support rendering sub-topic indexes
If the requested topic name is the name of a sub-topic, we now render
an index of topics within that sub-topic.
2015-12-30 17:34:51 -07:00
Anton Shestakov
2e206a44b7 hgweb: move entry-preparing code from webcommands to webutils.commonentry()
The new function is used to fill basic information about a ctx, such as
revision number and hash, author, commit message, etc. Before, every webcommand
used to get this basic information on its own using some boilerplate code, and
some things in some places just weren't available.
2015-11-13 14:35:36 +08:00
Yuya Nishihara
9ed442849f hgweb: load server settings from --web-conf (issue4699)
It copies the ui before loading the webconf and passes the copied ui only
to the service. This way, the hgwebdir app can reload configs cleanly.
2015-10-31 22:50:03 +09:00
Yuya Nishihara
5cfcdd71d7 hgweb: make sure command options are set to all ui objects
Before this patch, it was unclear why the httpservice object could read the
server options (e.g. --port) from 'ui'. It just worked because repo.ui is ui.
2015-11-21 13:28:12 +09:00
Yuya Nishihara
8d4fdbd827 hgweb: eliminate duck-typing to select hgweb or hgwebdir by command option
Since createservice() was moved to hgweb and hgweb imports both hgweb_mod and
hgwebdir_mod, we no longer have to force hgweb() function to select one of
them by the type of 'o' variable. Let's be explicit!

This patch does not change hgweb() function because it is the interface of
existing WSGI and CGI scripts.
2015-10-31 22:26:50 +09:00
Anton Shestakov
4f46ce6f31 webcommands: test that fctx is not None in filediff()
A block of code above this one already says "if fctx is not None", and it's
also what this code actually intends to check, so let's be specific as PEP-8
recommends.
2015-11-28 17:06:29 +08:00
Anton Shestakov
7359ceac6b webcommands: stop using ersatz if-else ternary operator for rename variable
c0ebd60607e9 didn't remove it, let's do it now.

Placing the added lines into the already existing "if fctx is not None" block
also makes webcommands.comparison() look a bit more like
webcommands.filediff(), which eases possible future refactoring. And fctx is
not None only when path in ctx, so logically it's equivalent.
2015-11-28 16:46:31 +08:00
Anton Shestakov
9f284e62ca webcommands: get correct parents when comparing a removed file (issue4962)
When comparing a file that was removed at the current revision, parents used to
show grandparents instead, due to how fctx was "shifted" from the current
revision to its p1. Let's not do that.

The fix is pretty much copied from webcommands.filediff().
2015-11-28 16:02:22 +08:00
Yuya Nishihara
c64bc024c8 hgweb: extract factory function of httpservice object
The next patch will merge the cmdutil.service() calls of both commandserver
and hgweb. Before doing it, this patch wipes out the code specific to hgweb
from commands.serve().
2015-10-31 22:15:16 +09:00
Yuya Nishihara
4fb8995ece hgweb: move httpservice object from commands module
This avoids the deep import of hgweb.server at the commands module.
2015-10-31 21:57:45 +09:00
Anton Shestakov
5c74a8a582 paper: show current revision on file log page
Most of the pages in paper (and coal) style show the current revision and its
branch, tags and bookmarks. Let's also show all this on file log page.
2015-11-13 18:31:58 +08:00
Yuya Nishihara
47690f822c hgweb: use absolute_import 2015-10-31 22:07:40 +09:00
Yuya Nishihara
6f91677786 hgweb: import wsgicgi at top level
There should be no practical reason to delay the import of wsgicgi.
2015-11-01 15:09:35 +09:00
Yuya Nishihara
3a2ca88d5a hgweb: import BaseHTTPServer as module at top level
This will avoid future warning spotted by the import checker.
2015-11-01 15:07:08 +09:00
Yuya Nishihara
e142543972 hgweb: do not import hgweb_mod.hgweb and .makebreadcrumb as symbol
It will be enforced by the import checker.
2015-11-01 14:23:23 +09:00
Anton Shestakov
53412195f4 webutil: make _siblings into an object with __iter__ and __len__
_siblings is a helper that is used for displaying changeset parents and
children in hgweb. Before, when it was a simple generator, it couldn't tell its
length without being consumed, and that required a special case when preparing
data for changeset template (see 3468fd599ef4).

Let's make it into a class (similar to templatekw._hybrid) that allows len(...)
without side-effects.
2015-11-10 17:22:40 +08:00
Yuya Nishihara
8110fbc21f hgweb: unify import style of error classes
It will be enforced by the import checker.
2015-11-01 14:43:25 +09:00
Yuya Nishihara
01e2649d34 hgweb: do not import templatefilters.revescape and websub as symbol
It will be enforced by the import checker.
2015-11-01 14:00:14 +09:00
Yuya Nishihara
ad55f13658 hgweb: alias ui module as uimod
It will be enforced by the import checker.
2015-11-01 13:58:32 +09:00
Anton Shestakov
90da27730e hgweb: compute changeset parents and children for log pages lazily
Log pages, i.e. changelog, filelog and search results page computed children
and parents for each changeset shown, because spartan hgweb style shows this
info. Turns out, computing all this is heavy and also unnecessary for log pages
in all other hgweb styles.

Luckily, templates allow an easy way to do computations on demand: just pass
the heavy part of code as a callable and it will be only called when needed.

Here are some benchmarks on the mercurial repository (best of 3):

time wget http://127.0.0.1:8021/

before: 0m0.050s
after:  0m0.040s

time wget http://127.0.0.1:8021/?revcount=960

before: 0m1.164s
after:  0m0.389s

time wget http://127.0.0.1:8021/log/tip/mercurial/commands.py

before: 0m0.047s
after:  0m0.042s

time wget http://127.0.0.1:8021/log/tip/mercurial/commands.py?revcount=960

before: 0m0.830s
after:  0m0.434s
2015-11-10 23:02:59 +08:00
Siddharth Agarwal
6b30464363 hgweb.server: drop support for Python 2.4 2015-10-24 16:23:42 -07:00
Anton Shestakov
9b60cbd85f hgweb: replace some str.split() calls by str.partition() or str.rpartition()
Since Python 2.5 str has new methods: partition and rpartition. They are more
specialized than the usual split and rsplit, and they sometimes convey the
intent of code better and also are a bit faster (faster than split/rsplit with
maxsplit specified). Let's use them in appropriate places for a small speedup.

Example performance (partition):

$ python -m timeit 'assert "apple|orange|banana".split("|")[0] == "apple"'
1000000 loops, best of 3: 0.376 usec per loop

$ python -m timeit 'assert "apple|orange|banana".split("|", 1)[0] == "apple"'
1000000 loops, best of 3: 0.327 usec per loop

$ python -m timeit 'assert "apple|orange|banana".partition("|")[0] == "apple"'
1000000 loops, best of 3: 0.214 usec per loop

Example performance (rpartition):

$ python -m timeit 'assert "apple|orange|banana".rsplit("|")[-1] == "banana"'
1000000 loops, best of 3: 0.372 usec per loop

$ python -m timeit 'assert "apple|orange|banana".rsplit("|", 1)[-1] == "banana"'
1000000 loops, best of 3: 0.332 usec per loop

$ python -m timeit 'assert "apple|orange|banana".rpartition("|")[-1] == "banana"'
1000000 loops, best of 3: 0.219 usec per loop
2015-11-02 23:37:49 +08:00
Mads Kiilerich
09567db49a spelling: trivial spell checking 2015-10-17 00:58:46 +02:00
Pierre-Yves David
30913031d4 error: get Abort from 'error' instead of 'util'
The home of 'Abort' is 'error' not 'util' however, a lot of code seems to be
confused about that and gives all the credit to 'util' instead of the
hardworking 'error'. In a spirit of equity, we break the cycle of injustice and
give back to 'error' the respect it deserves. And screw that 'util' poser.

For great justice.
2015-10-08 12:55:45 -07:00
Matt Mackall
5e1b4ad958 urls: bulk-change primary website URLs 2015-09-30 15:43:49 -05:00
Yuya Nishihara
d7b6a95763 hgweb: overwrite cwd to resolve file patterns relative to repo (issue4568)
It's useless to handle file patterns as relative to the cwd of the server
process. The only sensible way in hgweb is to resolve paths relative to the
repository root.

It seems dirstate.getcwd() isn't used to get a real file path, so this patch
won't cause problem.
2015-09-20 20:11:31 +09:00
Gregory Szorc
4e3c6d9b7a hgweb: consume generator inside context manager (issue4756)
If code inside a context manager returns a generator, the context
manager exits before the generator is iterated.

hgweb was using a context manager to control thread safe access to a
localrepository instance. But it was returning a generator, so there was
a race condition between a previous request streaming a response to the
client and a new request obtaining the released but in use repository.
By iterating the generator inside the context manager, we ensure we
don't release the repo instance until after the response has finished.

With this change, hgweb finally appears to have full localrepository
isolation between threads. I can no longer reproduce the 2 exceptions
reported in issue4756.

test-hgweb-non-interactive.t has been modified to consume the output
of calling into a WSGI application. Without this, execution of the WSGI
application stalls because of the added yield statement.
2015-09-12 12:16:39 -07:00
Gregory Szorc
216aba88f8 hg: always create new localrepository instance
cachedlocalrepo.copy() didn't actually create new localrepository
instances. This meant that the new thread isolation code in hgweb wasn't
actually using separate localrepository instances, even though it was
properly using separate cachedlocalrepo instances.

Because the behavior of the API changed, the single caller in hgweb had
to be refactored to always call _webifyrepo() or it may not have used
the proper filter.

I confirmed via print() debugging that id(repo) is in fact different on
each thread. This was not the case before.

For reasons I can't yet explain, this does not fix issue4756. I suspect
there is shared cache somewhere that isn't thread safe.
2015-09-12 11:31:56 -07:00
Matt Mackall
a8c75dcbec hgweb: drop unused import 2015-09-11 12:48:09 -07:00
Gregory Szorc
39247b40e9 hgweb: use separate repo instances per thread
Before this change, multiple threads/requests could share a
localrepository instance. This meant that all of localrepository needed
to be thread safe. Many bugs have been reported telling us that
localrepository isn't actually thread safe.

While making localrepository thread safe is a noble cause, it is a lot
of work. And there is little gain from doing so. Due to Python's GIL,
only 1 thread may be processing Python code at a time. The benefits
to multi-threaded servers are marginal.

Thread safety would be a lot of work for little gain. So, we're not
going to even attempt it.

This patch establishes a pool of repos in hgweb. When a request arrives,
we obtain the most recently used repository from the pool or create a
new one if none is available. When the request has finished, we put that
repo back in the pool.

We start with a pool size of 1. For servers using a single thread, the
pool will only ever be of size 1. For multi-threaded servers, the pool
size will grow to the max number of simultaneous requests the server
processes.

No logic for pruning the pool has been implemented. We assume server
operators either limit the number of threads to something they can
handle or restart the Mercurial process after a certain amount of
requests or time has passed.
2015-08-22 18:43:24 -07:00
Gregory Szorc
83818c1fca hg: establish a cache for localrepository instances
hgweb contained code for determining whether a cached localrepository
instance was up to date. This code was way too low-level to be in
hgweb.

This functionality has been moved to a new "cachedlocalrepo" class
in hg.py. The code has been changed slightly to facilitate use
inside a class. hgweb has been refactored to use the new API.

As part of this refactor, hgweb.repo no longer exists! We're very close
to using a distinct repo instance per thread.

The new cache records state when it is created. This intelligence
prevents an extra localrepository from being created on the first
hgweb request. This is why some redundant output from test-extension.t
has gone away.
2015-08-22 18:54:34 -07:00
Gregory Szorc
2aa478bfd2 hgweb: create function to perform actions on new repo
We perform some common tasks when a new repo instance is obtained. In
preparation for changing how we obtain repo instances, factor this
functionality into a standalone function.
2015-08-22 18:15:42 -07:00
Gregory Szorc
e03cfea13e hgweb: remove proxy to hgweb instance
We were temporarily routing attributes until all request-specific
attributes from hgweb were moved to requestcontext. We have finally
reached that juncture and we can remove the proxy.

At this point, only the repo instance is prone to race conditions
between threads. This will be dealt with shortly.
2015-08-22 17:50:28 -07:00
Gregory Szorc
fc3513ba2d hgweb: assign ctype to requestcontext
The very existence of ctype is a bit hacky. But we roll with it.

Before this patch, there was possibly a race condition between 2
threads handling file requests: 1 thread could set the ctype and
another serving a different file would read and use that potentially
wrong ctype.
2015-08-22 17:08:37 -07:00
Gregory Szorc
e74f9acd5d hgweb: add reponame to requestcontext
We have to use object.__setattr__ until the app proxy is gone.
2015-08-22 17:04:24 -07:00
Gregory Szorc
c3d67d78b9 hgweb: don't access self.repo during request processing
We want all repository accesses to go through requestcontext.repo
so the request is isolated from the application.
2015-08-22 16:54:52 -07:00
Gregory Szorc
29e7feecf4 hgweb: extract _getview to own function
While we're refactoring code, we might as well remove a method that
doesn't need to be a method.
2015-08-22 16:44:36 -07:00