From 244572480411f6e61b1ed38feacdba634f45d843 Mon Sep 17 00:00:00 2001 From: sumeshi Date: Mon, 12 Jan 2026 05:51:42 +0900 Subject: [PATCH 1/2] fix: switch MS API from HTML to JSON --- Mido.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Mido.sh b/Mido.sh index 9b517d0..e989b87 100755 --- a/Mido.sh +++ b/Mido.sh @@ -354,41 +354,46 @@ consumer_download() { # SKU ID: This specifies the language of the ISO. We always use "English (United States)", however, the SKU for this changes with each Windows release # We must make this request so our next one will be allowed # --data "" is required otherwise no "Content-Length" header will be sent causing HTTP response "411 Length Required" - language_skuid_table_html="$(curl --request POST --user-agent "$user_agent" --data "" --header "Accept:" --max-filesize 10K --fail --proto =https --tlsv1.2 --http1.1 -- "https://www.microsoft.com/en-US/api/controls/contentinclude/html?pageId=a8f8f489-4c7f-463a-9ca6-5cff94d8d041&host=www.microsoft.com&segments=software-download,$url_segment_parameter&query=&action=getskuinformationbyproductedition&sessionId=$session_id&productEditionId=$product_edition_id&sdVersion=2")" || { + profile="606624d44113" + language_skuid_table_json="$(curl --user-agent "$user_agent" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://www.microsoft.com/software-download-connector/api/getskuinformationbyproductedition?profile=${profile}&ProductEditionId=${product_edition_id}&SKU=undefined&friendlyFileName=undefined&Locale=en-US&sessionID=${session_id}")" || { handle_curl_error $? return $? } # tr: Filter for only alphanumerics or "-" to prevent HTTP parameter injection - sku_id="$(echo "$language_skuid_table_html" | grep "English (United States)" | sed 's/"//g' | cut -d ',' -f 1 | cut -d ':' -f 2 | tr -cd '[:alnum:]-' | head -c 16)" + sku_id="$(printf '%s' "$language_skuid_table_json" | tr -d '\n' | sed -n 's/.*"LocalizedLanguage":"English (United States)"[^}]*"Id":"\([^"]*\)".*/\1/p')" + if ! [ "$sku_id" ]; then + sku_id="$(printf '%s' "$language_skuid_table_json" | tr -d '\n' | sed -n 's/.*"Id":"\([^"]*\)"[^}]*"LocalizedLanguage":"English (United States)".*/\1/p')" + fi + sku_id="$(printf '%s' "$sku_id" | tr -cd '[:alnum:]-' | head -c 16)" [ "$VERBOSE" ] && echo "SKU ID: $sku_id" >&2 # Get ISO download link # If any request is going to be blocked by Microsoft it's always this last one (the previous requests always seem to succeed) # --referer: Required by Microsoft servers to allow request - iso_download_link_html="$(curl --request POST --user-agent "$user_agent" --data "" --referer "$url" --header "Accept:" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://www.microsoft.com/en-US/api/controls/contentinclude/html?pageId=6e2a1789-ef16-4f27-a296-74ef7ef5d96b&host=www.microsoft.com&segments=software-download,$url_segment_parameter&query=&action=GetProductDownloadLinksBySku&sessionId=$session_id&skuId=$sku_id&language=English&sdVersion=2")" || { + iso_download_link_json="$(curl --user-agent "$user_agent" --referer "$url" --max-filesize 100K --fail --proto =https --tlsv1.2 --http1.1 -- "https://www.microsoft.com/software-download-connector/api/GetProductDownloadLinksBySku?profile=${profile}&productEditionId=undefined&SKU=${sku_id}&friendlyFileName=undefined&Locale=en-US&sessionID=${session_id}")" || { # This should only happen if there's been some change to how this API works handle_curl_error $? return $? } - if ! [ "$iso_download_link_html" ]; then + if ! [ "$iso_download_link_json" ]; then # This should only happen if there's been some change to how this API works echo_err "Microsoft servers gave us an empty response to our request for an automated download. Please manually download this ISO in a web browser: $url" manual_verification="true" return 1 fi - if echo "$iso_download_link_html" | grep -q "We are unable to complete your request at this time."; then + if echo "$iso_download_link_json" | grep -q "Sentinel marked this request as rejected."; then echo_err "Microsoft blocked the automated download request based on your IP address. Please manually download this ISO in a web browser here: $url" manual_verification="true" return 1 fi # Filter for 64-bit ISO download URL - # sed: HTML decode "&" character + # sed: Decode some JSON escaped characters # tr: Filter for only alphanumerics or punctuation - iso_download_link="$(echo "$iso_download_link_html" | grep -o "https://software.download.prss.microsoft.com.*IsoX64" | cut -d '"' -f 1 | sed 's/&/\&/g' | tr -cd '[:alnum:][:punct:]' | head -c 512)" + iso_download_link="$(printf '%s' "$iso_download_link_json" | tr -d '\n' | grep -o '"Uri":"[^"]*"' | sed 's/"Uri":"//; s/"$//' | sed 's/\\u0026/\&/g; s@\\u002f@/@g; s@\\/@/@g' | grep -i 'x64' | tr -cd '[:alnum:][:punct:]' | head -c 512)" if ! [ "$iso_download_link" ]; then # This should only happen if there's been some change to the download endpoint web address From 2fffcd19e9f0b2006fb5f85faa37106f120f6527 Mon Sep 17 00:00:00 2001 From: sumeshi Date: Mon, 12 Jan 2026 06:15:17 +0900 Subject: [PATCH 2/2] fix: send UA/Referer when downloading consumer ISO --- Mido.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Mido.sh b/Mido.sh index e989b87..4c84241 100755 --- a/Mido.sh +++ b/Mido.sh @@ -236,12 +236,19 @@ scurl_file() { out_file="$1" tls_version="$2" url="$3" + user_agent="$4" + referer="$5" part_file="${out_file}${part_ext}" + set -- --progress-bar --location --output "$part_file" --continue-at - --max-filesize 10G --fail --proto =https "--tlsv$tls_version" --http1.1 + [ "$user_agent" ] && set -- "$@" --user-agent "$user_agent" + [ "$referer" ] && set -- "$@" --referer "$referer" + set -- "$@" -- "$url" + # --location: Microsoft likes to change which endpoint these downloads are stored on but is usually kind enough to add redirects # --fail: Return an error on server errors where the HTTP response code is 400 or greater - curl --progress-bar --location --output "$part_file" --continue-at - --max-filesize 10G --fail --proto =https "--tlsv$tls_version" --http1.1 -- "$url" || { + curl "$@" || { error_code=$? handle_curl_error "$error_code" error_action=$? @@ -405,7 +412,7 @@ consumer_download() { echo_ok "Got latest ISO download link (valid for 24 hours): $iso_download_link" # Download ISO - scurl_file "$out_file" "1.3" "$iso_download_link" + scurl_file "$out_file" "1.3" "$iso_download_link" "$user_agent" "$url" } enterprise_eval_download() {