diff --git a/changedetectionio/__init__.py b/changedetectionio/__init__.py
index 0af94a48..4b812758 100644
--- a/changedetectionio/__init__.py
+++ b/changedetectionio/__init__.py
@@ -445,6 +445,8 @@ def changedetection_app(config=None, datastore_o=None):
'tag': form.tag.data.strip(),
'title': form.title.data.strip(),
'headers': form.headers.data,
+ 'body': form.body.data,
+ 'method': form.method.data,
'fetch_backend': form.fetch_backend.data,
'trigger_text': form.trigger_text.data,
'notification_title': form.notification_title.data,
diff --git a/changedetectionio/content_fetcher.py b/changedetectionio/content_fetcher.py
index d1eb41b9..b2a2d794 100644
--- a/changedetectionio/content_fetcher.py
+++ b/changedetectionio/content_fetcher.py
@@ -131,10 +131,12 @@ class html_webdriver(Fetcher):
class html_requests(Fetcher):
fetcher_description = "Basic fast Plaintext/HTTP Client"
- def run(self, url, timeout, request_headers):
+ def run(self, url, timeout, request_headers, request_body, request_method):
import requests
- r = requests.get(url,
+ r = requests.request(method=request_method,
+ data=request_body,
+ url=url,
headers=request_headers,
timeout=timeout,
verify=False)
diff --git a/changedetectionio/fetch_site_status.py b/changedetectionio/fetch_site_status.py
index fc8c1e6e..69ff7de0 100644
--- a/changedetectionio/fetch_site_status.py
+++ b/changedetectionio/fetch_site_status.py
@@ -80,6 +80,8 @@ class perform_site_check():
else:
timeout = self.datastore.data['settings']['requests']['timeout']
url = self.datastore.get_val(uuid, 'url')
+ request_body = self.datastore.get_val(uuid, 'body')
+ request_method = self.datastore.get_val(uuid, 'method')
# Pluggable content fetcher
prefer_backend = watch['fetch_backend']
@@ -91,7 +93,7 @@ class perform_site_check():
fetcher = klass()
- fetcher.run(url, timeout, request_headers)
+ fetcher.run(url, timeout, request_headers, request_body, request_method)
# Fetching complete, now filters
# @todo move to class / maybe inside of fetcher abstract base?
diff --git a/changedetectionio/forms.py b/changedetectionio/forms.py
index 1028c213..dc06c67a 100644
--- a/changedetectionio/forms.py
+++ b/changedetectionio/forms.py
@@ -8,6 +8,16 @@ import re
from changedetectionio.notification import default_notification_format, valid_notification_formats, default_notification_body, default_notification_title
+valid_method = {
+ 'GET',
+ 'POST',
+ 'PUT',
+ 'PATCH',
+ 'DELETE',
+}
+
+default_method = 'GET'
+
class StringListField(StringField):
widget = widgets.TextArea()
@@ -224,8 +234,22 @@ class watchForm(commonSettingsForm):
ignore_text = StringListField('Ignore Text', [ValidateListRegex()])
headers = StringDictKeyValue('Request Headers')
+ body = TextAreaField('Request Body', [validators.Optional()])
+ method = SelectField('Request Method', choices=valid_method, default=default_method)
trigger_text = StringListField('Trigger/wait for text', [validators.Optional(), ValidateListRegex()])
+ def validate(self, **kwargs):
+ if not super().validate():
+ return False
+
+ result = True
+
+ # Fail form validation when a body is set for a GET
+ if self.method.data == 'GET' and self.body.data:
+ self.body.errors.append('Body must be empty when Request Method is set to GET')
+ result = False
+
+ return result
class globalSettingsForm(commonSettingsForm):
diff --git a/changedetectionio/store.py b/changedetectionio/store.py
index 5728cbb5..60f3d826 100644
--- a/changedetectionio/store.py
+++ b/changedetectionio/store.py
@@ -70,6 +70,8 @@ class ChangeDetectionStore:
'previous_md5': "",
'uuid': str(uuid_builder.uuid4()),
'headers': {}, # Extra headers to send
+ 'body': None,
+ 'method': 'GET',
'history': {}, # Dict of timestamp and output stripped filename
'ignore_text': [], # List of text to ignore when calculating the comparison checksum
# Custom notification content
diff --git a/changedetectionio/templates/edit.html b/changedetectionio/templates/edit.html
index c4f6ee62..4b62bcd9 100644
--- a/changedetectionio/templates/edit.html
+++ b/changedetectionio/templates/edit.html
@@ -9,6 +9,7 @@
-
{{ render_field(form.fetch_backend) }}
@@ -62,6 +55,26 @@ User-Agent: wonderbra 1.0") }}
+
+
Note: These settings are ONLY used by Basic fast Plaintext/HTTP Client.
+
+
+ {{ render_field(form.body, rows=5, placeholder="Example
+{
+ \"name\":\"John\",
+ \"age\":30,
+ \"car\":null
+}") }}
+
+
+ {{ render_field(form.method) }}
+
+
+
Note: These settings override the global settings.