Customizable User agent

This commit is contained in:
Dejvino 2026-07-30 18:15:42 +02:00
parent 8d1488f354
commit c283c47cef
4 changed files with 32 additions and 2 deletions

View File

@ -11,4 +11,5 @@ SERVER="" # server hostname, optionally with subdirectories
STATUS="draft" # one of publish,future,draft,pending,private STATUS="draft" # one of publish,future,draft,pending,private
CATEGORIES="" # comma separated integer IDs of categories CATEGORIES="" # comma separated integer IDs of categories
TAGS="" # comma separated integer IDs of tags 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

View File

@ -11,6 +11,7 @@ STATUS="draft" # one of publish,future,draft,pending,private
CATEGORIES="" # comma separated integer IDs of categories CATEGORIES="" # comma separated integer IDs of categories
TAGS="" # comma separated integer IDs of tags TAGS="" # comma separated integer IDs of tags
TMPFILE=/tmp/wordpress-post.txt # location of a temporary file with the post text 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}" CONFIG_DIR="${WORDPRESS_REST_CURL_CONFIG_DIR:-$HOME/.config/wordpress-rest-curl}"
# CLI options: # CLI options:
@ -129,12 +130,14 @@ PAYLOAD=$(jq -n \
BASE_URL="$SERVER" BASE_URL="$SERVER"
[[ "$BASE_URL" != http://* && "$BASE_URL" != https://* ]] && BASE_URL="https://$BASE_URL" [[ "$BASE_URL" != http://* && "$BASE_URL" != https://* ]] && BASE_URL="https://$BASE_URL"
BASE_URL="${BASE_URL%/}"
URL="$BASE_URL/wp-json/wp/v2/posts/" URL="$BASE_URL/wp-json/wp/v2/posts/"
[[ -n "$POST_ID" ]] && URL="$BASE_URL/wp-json/wp/v2/posts/$POST_ID" [[ -n "$POST_ID" ]] && URL="$BASE_URL/wp-json/wp/v2/posts/$POST_ID"
# push the post! # push the post!
RESPONSE=$(curl --silent --show-error --user "$USER:$PASSWORD" -X POST \ RESPONSE=$(curl --silent --show-error --user "$USER:$PASSWORD" -X POST \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-A "$USER_AGENT" \
--data "$PAYLOAD" \ --data "$PAYLOAD" \
-w '\n%{http_code}' \ -w '\n%{http_code}' \
"$URL") "$URL")

View File

@ -7,7 +7,8 @@
# determines the response to the next request. If absent, responds # determines the response to the next request. If absent, responds
# 201 with the submitted fields echoed back under an "id". # 201 with the submitted fields echoed back under an "id".
# MOCK_WP_REQUEST_FILE - overwritten on every request with # 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). # 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")} data = {"_raw": body.decode(errors="replace")}
with open(REQUEST_FILE, "w") as f: 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} status, resp_body = 201, {"id": 1, **data}
if os.path.exists(CONTROL_FILE): if os.path.exists(CONTROL_FILE):

View File

@ -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: 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: tags sent as array" "[10]" "$(jq -c '.payload.tags' <<<"$REQ")"
assert_eq "create: content rendered as markdown" "true" "$(jq -r '.payload.content | test("<strong>markdown</strong>")' <<<"$REQ")" assert_eq "create: content rendered as markdown" "true" "$(jq -r '.payload.content | test("<strong>markdown</strong>")' <<<"$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" <<EOF3
SERVER="http://127.0.0.1:$PORT/"
EOF3
run_post_sh --file "$POST_FILE" >/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 --- # --- edit an existing post ---
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE" rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"