tests/test-http-api-httpv2.t
author Gregory Szorc <gregory.szorc@gmail.com>
Tue, 13 Mar 2018 16:53:21 -0700
changeset 37049 1cfef5693203
child 37050 fddcb51b5084
permissions -rw-r--r--
wireproto: support /api/* URL space for exposing APIs I will soon be introducing a new version of the HTTP wire protocol. One of the things I want to change with it is the URL routing. I want to rely on URL paths to define endpoints rather than the "cmd" query string argument. That should be pretty straightforward. I was thinking about what URL space to reserve for the new protocol. We /could/ put everything at a top-level path. e.g. /wireproto/* or /http-v2-wireproto/*. However, these constrain us a bit because they assume there will only be 1 API: version 2 of the HTTP wire protocol. I think there is room to grow multiple APIs. For example, there may someday be a proper JSON API to query or even manipulate the repository. And I don't think we should have to create a new top-level URL space for each API nor should we attempt to shoehorn each future API into the same shared URL space: that would just be too chaotic. This commits reserves the /api/* URL space for all our future API needs. Essentially, all requests to /api/* get routed to a new WSGI handler. By default, it 404's the entire URL space unless the "api server" feature is enabled. When enabled, requests to "/api" list available APIs. URLs of the form /api/<name>/* are reserved for a particular named API. Behavior within each API is left up to that API. So, we can grow new APIs easily without worrying about URL space conflicts. APIs can be registered by adding entries to a global dict. This allows extensions to provide their own APIs should they choose to do so. This is probably a premature feature. But IMO the code is easier to read if we're not dealing with API-specific behavior like config option querying inline. To prove it works, we implement a very basic API for version 2 of the HTTP wire protocol. It does nothing of value except facilitate testing of the /api/* URL space. We currently emit plain text responses for all /api/* endpoints. There's definitely room to look at Accept and other request headers to vary the response format. But we have to start somewhere. Differential Revision: https://phab.mercurial-scm.org/D2834
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37049
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
  $ send() {
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
  >   hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     3
  > }
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
  $ hg init server
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
  $ cat > server/.hg/hgrc << EOF
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
  > [experimental]
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
  > web.apiserver = true
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
  > EOF
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    10
  $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
  $ cat hg.pid > $DAEMON_PIDS
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
HTTP v2 protocol not enabled by default
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    14
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    15
  $ send << EOF
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    16
  > httprequest GET api/exp-http-v2-0001
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    17
  >     user-agent: test
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
  > EOF
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    19
  using raw connection to peer
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    20
  s>     GET /api/exp-http-v2-0001 HTTP/1.1\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    21
  s>     Accept-Encoding: identity\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    22
  s>     user-agent: test\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    23
  s>     host: $LOCALIP:$HGPORT\r\n (glob)
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    24
  s>     \r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    25
  s> makefile('rb', None)
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    26
  s>     HTTP/1.1 404 Not Found\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    27
  s>     Server: testing stub value\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    28
  s>     Date: $HTTP_DATE$\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    29
  s>     Content-Type: text/plain\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    30
  s>     Content-Length: 33\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    31
  s>     \r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    32
  s>     API exp-http-v2-0001 not enabled\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    33
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    34
Restart server with support for HTTP v2 API
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    35
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    36
  $ killdaemons.py
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    37
  $ cat > server/.hg/hgrc << EOF
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    38
  > [experimental]
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    39
  > web.apiserver = true
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    40
  > web.api.http-v2 = true
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    41
  > EOF
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    42
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    43
  $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    44
  $ cat hg.pid > $DAEMON_PIDS
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    45
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    46
Requests simply echo their path (for now)
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    47
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    48
  $ send << EOF
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    49
  > httprequest GET api/exp-http-v2-0001/path1/path2
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    50
  >     user-agent: test
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    51
  > EOF
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    52
  using raw connection to peer
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    53
  s>     GET /api/exp-http-v2-0001/path1/path2 HTTP/1.1\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    54
  s>     Accept-Encoding: identity\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    55
  s>     user-agent: test\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    56
  s>     host: $LOCALIP:$HGPORT\r\n (glob)
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    57
  s>     \r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    58
  s> makefile('rb', None)
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    59
  s>     HTTP/1.1 200 OK\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    60
  s>     Server: testing stub value\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    61
  s>     Date: $HTTP_DATE$\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    62
  s>     Content-Type: text/plain\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    63
  s>     Content-Length: 12\r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    64
  s>     \r\n
1cfef5693203 wireproto: support /api/* URL space for exposing APIs
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    65
  s>     path1/path2\n