From c283c47cef8012509f62f283e7725963addaa3ca Mon Sep 17 00:00:00 2001 From: Dejvino Date: Thu, 30 Jul 2026 18:15:42 +0200 Subject: [PATCH] Customizable User agent --- config.sh.template | 1 + post.sh | 3 +++ tests/mock_wp_server.py | 9 +++++++-- tests/run_tests.sh | 21 +++++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/config.sh.template b/config.sh.template index d0e5e54..066154d 100755 --- a/config.sh.template +++ b/config.sh.template @@ -11,4 +11,5 @@ SERVER="" # server hostname, optionally with subdirectories STATUS="draft" # one of publish,future,draft,pending,private CATEGORIES="" # comma separated integer IDs of categories TAGS="" # comma separated integer IDs of tags +# USER_AGENT="Mozilla/5.0 (X11; Linux x86_64) wordpress-rest-curl/1.0" # uncomment to override; some hosts' DDoS/bot protection blocks curl's default UA diff --git a/post.sh b/post.sh index b6b7744..aafb5af 100755 --- a/post.sh +++ b/post.sh @@ -11,6 +11,7 @@ STATUS="draft" # one of publish,future,draft,pending,private CATEGORIES="" # comma separated integer IDs of categories TAGS="" # comma separated integer IDs of tags TMPFILE=/tmp/wordpress-post.txt # location of a temporary file with the post text +USER_AGENT="Mozilla/5.0 (X11; Linux x86_64) wordpress-rest-curl/1.0" # some hosts block curl's default UA as bot traffic CONFIG_DIR="${WORDPRESS_REST_CURL_CONFIG_DIR:-$HOME/.config/wordpress-rest-curl}" # CLI options: @@ -129,12 +130,14 @@ PAYLOAD=$(jq -n \ BASE_URL="$SERVER" [[ "$BASE_URL" != http://* && "$BASE_URL" != https://* ]] && BASE_URL="https://$BASE_URL" +BASE_URL="${BASE_URL%/}" URL="$BASE_URL/wp-json/wp/v2/posts/" [[ -n "$POST_ID" ]] && URL="$BASE_URL/wp-json/wp/v2/posts/$POST_ID" # push the post! RESPONSE=$(curl --silent --show-error --user "$USER:$PASSWORD" -X POST \ -H "Content-Type: application/json" \ + -A "$USER_AGENT" \ --data "$PAYLOAD" \ -w '\n%{http_code}' \ "$URL") diff --git a/tests/mock_wp_server.py b/tests/mock_wp_server.py index 9940fa6..652656c 100755 --- a/tests/mock_wp_server.py +++ b/tests/mock_wp_server.py @@ -7,7 +7,8 @@ # determines the response to the next request. If absent, responds # 201 with the submitted fields echoed back under an "id". # MOCK_WP_REQUEST_FILE - overwritten on every request with -# {"path": ..., "payload": ...} so a test can assert on what was sent. +# {"path": ..., "payload": ..., "user_agent": ...} so a test can assert +# on what was sent. # # Listens on 127.0.0.1:$MOCK_WP_PORT (default 8899). @@ -30,7 +31,11 @@ class Handler(http.server.BaseHTTPRequestHandler): data = {"_raw": body.decode(errors="replace")} with open(REQUEST_FILE, "w") as f: - json.dump({"path": self.path, "payload": data}, f) + json.dump({ + "path": self.path, + "payload": data, + "user_agent": self.headers.get("User-Agent", ""), + }, f) status, resp_body = 201, {"id": 1, **data} if os.path.exists(CONTROL_FILE): diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 824b52e..df569e7 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -75,6 +75,27 @@ assert_eq "create: status" "publish" "$(jq -r '.payload.status' <<<"$REQ")" assert_eq "create: categories sent as array" "[3,7]" "$(jq -c '.payload.categories' <<<"$REQ")" assert_eq "create: tags sent as array" "[10]" "$(jq -c '.payload.tags' <<<"$REQ")" assert_eq "create: content rendered as markdown" "true" "$(jq -r '.payload.content | test("markdown")' <<<"$REQ")" +assert_eq "create: sends a non-default user agent" "true" "$(jq -r '.user_agent != "" and (.user_agent | test("^curl/") | not)' <<<"$REQ")" + +# --- USER_AGENT is configurable, e.g. to dodge a host's DDoS protection --- +rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE" +cat >> "$HOME/.config/wordpress-rest-curl/config.sh" <<'EOF3' +USER_AGENT="Mozilla/5.0 (test override)" +EOF3 +run_post_sh --file "$POST_FILE" >/dev/null +assert_eq "user agent: exit code" "0" "$?" +REQ=$(cat "$MOCK_WP_REQUEST_FILE") +assert_eq "user agent: override from config is sent" "Mozilla/5.0 (test override)" "$(jq -r '.user_agent' <<<"$REQ")" + +# --- trailing slash on SERVER doesn't produce a double slash in the URL --- +rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE" +cat >> "$HOME/.config/wordpress-rest-curl/config.sh" </dev/null +assert_eq "trailing slash: exit code" "0" "$?" +REQ=$(cat "$MOCK_WP_REQUEST_FILE") +assert_eq "trailing slash: path has no double slash" "/wp-json/wp/v2/posts/" "$(jq -r '.path' <<<"$REQ")" # --- edit an existing post --- rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"