Skip to content

Commit 2b3f0cb

Browse files
authored
Add all IANA assigned HTTP method names (#751)
* Ignore `docs/_build` * Remove `v` prefix from VERSION. Also added a `lib-doc` target * Raise a `ValueError` instead of `NotImplementedError` * Add all registered http method verbs * Generate `_scm_version.py` on every `make` invocation. Fix `v` prefix bug. * `+proxy` for emails * Make explicit that this script writes to file * `PROXY_AGENT_HEADER_VALUE` still needs the `v` :)
1 parent 658acd8 commit 2b3f0cb

File tree

11 files changed

+152
-48
lines changed

11 files changed

+152
-48
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ cover
2626
htmlcov
2727
dist
2828
build
29+
2930
proxy/public
31+
docs/_build

CODE_OF_CONDUCT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
5555
## Enforcement
5656

5757
Instances of abusive, harassing, or otherwise unacceptable behavior may be
58-
reported by contacting the project team at [email protected]. All
58+
reported by contacting the project team at mailsforabhinav+proxy@gmail.com. All
5959
complaints will be reviewed and investigated and will result in a response that
6060
is deemed necessary and appropriate to the circumstances. The project team is
6161
obligated to maintain confidentiality with regard to the reporter of an incident.

Makefile

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ SHELL := /bin/bash
22

33
NS ?= abhinavsingh
44
IMAGE_NAME ?= proxy.py
5-
VERSION ?= v$(shell ./scm-version.sh)
65
LATEST_TAG := $(NS)/$(IMAGE_NAME):latest
7-
IMAGE_TAG := $(NS)/$(IMAGE_NAME):$(VERSION)
6+
IMAGE_TAG := $(NS)/$(IMAGE_NAME):$(shell ./write-scm-version.sh)
87

98
HTTPS_KEY_FILE_PATH := https-key.pem
109
HTTPS_CERT_FILE_PATH := https-cert.pem
@@ -17,12 +16,14 @@ CA_SIGNING_KEY_FILE_PATH := ca-signing-key.pem
1716

1817
.PHONY: all https-certificates sign-https-certificates ca-certificates
1918
.PHONY: lib-check lib-clean lib-test lib-package lib-coverage lib-lint lib-pytest
20-
.PHONY: lib-release-test lib-release lib-profile
21-
.PHONY: lib-dep, lib-flake8, lib-mypy, lib-scm-version
19+
.PHONY: lib-release-test lib-release lib-profile lib-doc
20+
.PHONY: lib-dep lib-flake8 lib-mypy
2221
.PHONY: container container-run container-release
2322
.PHONY: devtools dashboard dashboard-clean
2423

25-
all: lib-test
24+
all:
25+
echo $(IMAGE_TAG)
26+
# lib-test
2627

2728
https-certificates:
2829
# Generate server key
@@ -82,14 +83,13 @@ lib-clean:
8283
rm -rf .hypothesis
8384

8485
lib-dep:
86+
pip install --upgrade pip && \
8587
pip install \
8688
-r requirements.txt \
8789
-r requirements-testing.txt \
8890
-r requirements-release.txt \
89-
-r requirements-tunnel.txt
90-
91-
lib-scm-version:
92-
@echo "version = '$(VERSION)'" > proxy/common/_scm_version.py
91+
-r requirements-tunnel.txt \
92+
-r docs/requirements.txt
9393

9494
lib-lint:
9595
python -m tox -e lint
@@ -114,6 +114,16 @@ lib-release-test: lib-package
114114
lib-release: lib-package
115115
twine upload dist/*
116116

117+
lib-doc:
118+
pushd docs && \
119+
python -m sphinx \
120+
--keep-going \
121+
-b dirhtml \
122+
-d _build/doctrees \
123+
-D language=en . _build/html && \
124+
popd && \
125+
open docs/_build/html/index.html
126+
117127
lib-coverage:
118128
pytest --cov=proxy --cov=tests --cov-report=html tests/
119129
open htmlcov/index.html

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ To start `proxy.py` from source code follow these instructions:
379379
- Install deps
380380

381381
```console
382-
❯ make lib-dep lib-scm-version
382+
❯ make lib-dep
383383
```
384384

385385
- Optionally, run tests

proxy/http/methods.py

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,91 @@
1616
from typing import NamedTuple
1717

1818

19+
# Ref: https://www.iana.org/assignments/http-methods/http-methods.xhtml
1920
HttpMethods = NamedTuple(
2021
'HttpMethods', [
22+
('ACL', bytes),
23+
('BASELINE_CONTROL', bytes),
24+
('BIND', bytes),
25+
('CHECKIN', bytes),
26+
('CHECKOUT', bytes),
27+
('CONNECT', bytes),
28+
('COPY', bytes),
29+
('DELETE', bytes),
2130
('GET', bytes),
2231
('HEAD', bytes),
32+
('LABEL', bytes),
33+
('LINK', bytes),
34+
('LOCK', bytes),
35+
('MERGE', bytes),
36+
('MKACTIVITY', bytes),
37+
('MKCALENDAR', bytes),
38+
('MKCOL', bytes),
39+
('MKREDIRECTREF', bytes),
40+
('MKWORKSPACE', bytes),
41+
('MOVE', bytes),
42+
('OPTIONS', bytes),
43+
('ORDERPATCH', bytes),
44+
('PATCH', bytes),
2345
('POST', bytes),
46+
('PRI', bytes),
47+
('PROPFIND', bytes),
48+
('PROPPATCH', bytes),
2449
('PUT', bytes),
25-
('DELETE', bytes),
26-
('CONNECT', bytes),
27-
('OPTIONS', bytes),
50+
('REBIND', bytes),
51+
('REPORT', bytes),
52+
('SEARCH', bytes),
2853
('TRACE', bytes),
29-
('PATCH', bytes),
54+
('UNBIND', bytes),
55+
('UNCHECKOUT', bytes),
56+
('UNLINK', bytes),
57+
('UNLOCK', bytes),
58+
('UPDATE', bytes),
59+
('UPDATEREDIRECTREF', bytes),
60+
('VERSION_CONTROL', bytes),
61+
('STAR', bytes),
3062
],
3163
)
3264

3365
httpMethods = HttpMethods(
66+
b'ACL',
67+
b'BASELINE-CONTROL',
68+
b'BIND',
69+
b'CHECKIN',
70+
b'CHECKOUT',
71+
b'CONNECT',
72+
b'COPY',
73+
b'DELETE',
3474
b'GET',
3575
b'HEAD',
76+
b'LABEL',
77+
b'LINK',
78+
b'LOCK',
79+
b'MERGE',
80+
b'MKACTIVITY',
81+
b'MKCALENDAR',
82+
b'MKCOL',
83+
b'MKREDIRECTREF',
84+
b'MKWORKSPACE',
85+
b'MOVE',
86+
b'OPTIONS',
87+
b'ORDERPATCH',
88+
b'PATCH',
3689
b'POST',
90+
b'PRI',
91+
b'PROPFIND',
92+
b'PROPPATCH',
3793
b'PUT',
38-
b'DELETE',
39-
b'CONNECT',
40-
b'OPTIONS',
94+
b'REBIND',
95+
b'REPORT',
96+
b'SEARCH',
4197
b'TRACE',
42-
b'PATCH',
98+
b'UNBIND',
99+
b'UNCHECKOUT',
100+
b'UNLINK',
101+
b'UNLOCK',
102+
b'UPDATE',
103+
b'UPDATEREDIRECTREF',
104+
b'VERSION-CONTROL',
105+
b'*',
43106
)

proxy/http/parser/parser.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -304,27 +304,25 @@ def _process_line_and_headers(self, raw: bytes) -> Tuple[bool, bytes]:
304304

305305
def _process_line(self, raw: bytes) -> None:
306306
if self.type == httpParserTypes.REQUEST_PARSER:
307-
# Ref:
308-
# https://datatracker.ietf.org/doc/html/rfc2616#section-5.1
309-
# https://greenbytes.de/tech/webdav/rfc7230.html#request.line
310-
# https://greenbytes.de/tech/webdav/rfc7231.html#methods
311-
# http://www.iana.org/assignments/http-methods/http-methods.xhtml
312307
if self.protocol is not None and self.protocol.version is None:
313308
# We expect to receive entire proxy protocol v1 line
314309
# in one network read and don't expect partial packets
315310
self.protocol.parse(raw)
316311
else:
312+
# Ref: https://datatracker.ietf.org/doc/html/rfc2616#section-5.1
317313
line = raw.split(WHITESPACE)
318314
if len(line) == 3:
319315
self.method = line[0].upper()
320316
self.set_url(line[1])
321317
self.version = line[2]
322318
self.state = httpParserStates.LINE_RCVD
323319
else:
324-
# raise exception
325-
# TODO, it would be better to use raise HttpProtocolException,
326-
# but we should solve circular import problem first
327-
raise NotImplementedError('Invalid request line')
320+
# To avoid a possible attack vector, we raise exception
321+
# if parser receives an invalid request line.
322+
#
323+
# TODO: Better to use raise HttpProtocolException,
324+
# but we should solve circular import problem first.
325+
raise ValueError('Invalid request line')
328326
else:
329327
line = raw.split(WHITESPACE)
330328
self.version = line[0]

scm-version.sh

Lines changed: 0 additions & 16 deletions
This file was deleted.

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description = ⚡⚡⚡Fast, Lightweight, Pluggable, TLS interception capable pr
77
long_description = file: README.md
88
long_description_content_type = text/markdown
99
author = Abhinav Singh
10-
author_email = [email protected]
10+
author_email = mailsforabhinav+proxy@gmail.com
1111
license = 'BSD'
1212
license_files =
1313
LICENSE.md

tests/http/test_http_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ def setUp(self) -> None:
2424
self.parser = HttpParser(httpParserTypes.REQUEST_PARSER)
2525

2626
def test_issue_127(self) -> None:
27-
with self.assertRaises(NotImplementedError):
27+
with self.assertRaises(ValueError):
2828
self.parser.parse(CRLF)
2929

30-
with self.assertRaises(NotImplementedError):
30+
with self.assertRaises(ValueError):
3131
raw = b'qwqrqw!@!#@!#ad adfad\r\n'
3232
while True:
3333
self.parser.parse(raw)

tests/http/test_protocol_handler.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,8 @@ def assert_data_queued(
397397
b'Via: 1.1 proxy.py v%s' % bytes_(__version__),
398398
CRLF,
399399
])
400-
server.queue.assert_called_once_with(pkt)
400+
server.queue.assert_called_once()
401+
self.assertEqual(server.queue.call_args_list[0][0][0].tobytes(), pkt)
401402
server.buffer_size.return_value = len(pkt)
402403

403404
def assert_data_queued_to_server(self, server: mock.Mock) -> None:

write-scm-version.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
#
3+
# write-scm-version.sh exists because `proxy.py``
4+
# auto-detects it's next version from git. Hence,
5+
# for `proxy.py` to work `proxy/common/_scm_version.py`
6+
# file must be auto-generated with necessary information.
7+
#
8+
# For CI/CD, this file is generated via `tox` integration.
9+
# For local development (without editable install), you
10+
# must run this script to pre-populate `_scm_version.py`.
11+
#
12+
# This file is integrated by default within `Makefile`.
13+
# For every make target invocation, `_scm_version.py` file
14+
# will be re-written.
15+
16+
# Guessed Version 2.3.2.dev146+gad54132.d20211114
17+
VERSION=$(python -m setuptools_scm --version | \
18+
# 2.3.2.dev146+gad54132.d20211114
19+
awk '{print $3}')
20+
21+
# Store default IFS
22+
OLDIFS=$IFS
23+
24+
IFS="+"
25+
set -- $VERSION
26+
SEMVER=$1
27+
DATE_AND_HASH=$2
28+
29+
IFS="."
30+
set -- $SEMVER
31+
MAJOR=$1
32+
MINOR=$2
33+
PATCH=$3
34+
DISTANCE=$4
35+
36+
# Reset IFS
37+
IFS=$OLDIFS
38+
39+
echo "# coding: utf-8
40+
# file generated by setuptools_scm
41+
# don't change, don't track in version control
42+
version = '${VERSION}'
43+
version_tuple = (${MAJOR}, ${MINOR}, ${PATCH}, '${DISTANCE}', '${DATE_AND_HASH}')" > \
44+
proxy/common/_scm_version.py
45+
46+
echo $MAJOR.$MINOR.$PATCH.$DISTANCE

0 commit comments

Comments
 (0)