Create new DTIRequests.{get,post} helpers for HTTP requests

Instead of using `Async::HTTP::Internet` directly, and always applying
our `User-Agent` header manually, let's build a helper for it!
This commit is contained in:
Emi Matchu 2024-12-16 14:04:22 -08:00
parent 5546d6df5d
commit 86205c5e44
6 changed files with 34 additions and 43 deletions

View file

@ -1,11 +1,6 @@
require "addressable/template" require "addressable/template"
require "async/http/internet/instance"
module Neopets::NCMall module Neopets::NCMall
# Share a pool of persistent connections, rather than reconnecting on
# each request. (This library does that automatically!)
INTERNET = Async::HTTP::Internet.instance
# Load the NC Mall home page content area, and return its useful data. # Load the NC Mall home page content area, and return its useful data.
HOME_PAGE_URL = "https://ncmall.neopets.com/mall/ajax/home_page.phtml" HOME_PAGE_URL = "https://ncmall.neopets.com/mall/ajax/home_page.phtml"
def self.load_home_page def self.load_home_page
@ -26,9 +21,7 @@ module Neopets::NCMall
PAGE_LINK_PATTERN = /load_items_pane\(['"](.+?)['"], ([0-9]+)\).+?>(.+?)</ PAGE_LINK_PATTERN = /load_items_pane\(['"](.+?)['"], ([0-9]+)\).+?>(.+?)</
def self.load_page_links def self.load_page_links
html = Sync do html = Sync do
INTERNET.get(ROOT_DOCUMENT_URL, [ DTIRequests.get(ROOT_DOCUMENT_URL) do |response|
["User-Agent", Rails.configuration.user_agent_for_neopets],
]) do |response|
if response.status != 200 if response.status != 200
raise ResponseNotOK.new(response.status), raise ResponseNotOK.new(response.status),
"expected status 200 but got #{response.status} (#{ROOT_DOCUMENT_URL})" "expected status 200 but got #{response.status} (#{ROOT_DOCUMENT_URL})"
@ -48,15 +41,14 @@ module Neopets::NCMall
STYLING_STUDIO_URL = "https://www.neopets.com/np-templates/ajax/stylingstudio/studio.php" STYLING_STUDIO_URL = "https://www.neopets.com/np-templates/ajax/stylingstudio/studio.php"
def self.load_styles(species_id:, neologin:) def self.load_styles(species_id:, neologin:)
Sync do Sync do
INTERNET.post( DTIRequests.post(
STYLING_STUDIO_URL, STYLING_STUDIO_URL,
headers: [ [
["User-Agent", Rails.configuration.user_agent_for_neopets],
["Content-Type", "application/x-www-form-urlencoded"], ["Content-Type", "application/x-www-form-urlencoded"],
["Cookie", "neologin=#{neologin}"], ["Cookie", "neologin=#{neologin}"],
["X-Requested-With", "XMLHttpRequest"], ["X-Requested-With", "XMLHttpRequest"],
], ],
body: {tab: 1, mode: "getStyles", species: species_id}.to_query, {tab: 1, mode: "getStyles", species: species_id}.to_query,
) do |response| ) do |response|
if response.status != 200 if response.status != 200
raise ResponseNotOK.new(response.status), raise ResponseNotOK.new(response.status),
@ -80,9 +72,7 @@ module Neopets::NCMall
def self.load_page_by_url(url) def self.load_page_by_url(url)
Sync do Sync do
INTERNET.get(url, [ DTIRequests.get(url) do |response|
["User-Agent", Rails.configuration.user_agent_for_neopets],
]) do |response|
if response.status != 200 if response.status != 200
raise ResponseNotOK.new(response.status), raise ResponseNotOK.new(response.status),
"expected status 200 but got #{response.status} (#{url})" "expected status 200 but got #{response.status} (#{url})"

View file

@ -1,12 +1,6 @@
require "async/http/internet/instance"
# While most of our NeoPass logic is built into Devise -> OmniAuth -> OIDC # While most of our NeoPass logic is built into Devise -> OmniAuth -> OIDC
# OmniAuth plugin, NeoPass also offers some supplemental APIs that we use here. # OmniAuth plugin, NeoPass also offers some supplemental APIs that we use here.
module Neopets::NeoPass module Neopets::NeoPass
# Share a pool of persistent connections, rather than reconnecting on
# each request. (This library does that automatically!)
INTERNET = Async::HTTP::Internet.instance
def self.load_main_neopets_username(access_token) def self.load_main_neopets_username(access_token)
linkages = load_linkages(access_token) linkages = load_linkages(access_token)
@ -32,10 +26,10 @@ module Neopets::NeoPass
LINKAGE_URL = "https://oidc.neopets.com/linkage/all" LINKAGE_URL = "https://oidc.neopets.com/linkage/all"
def self.load_linkages(access_token) def self.load_linkages(access_token)
linkages_str = Sync do linkages_str = Sync do
INTERNET.get(LINKAGE_URL, [ DTIRequests.get(
["User-Agent", Rails.configuration.user_agent_for_neopets], LINKAGE_URL,
["Authorization", "Bearer #{access_token}"], [["Authorization", "Bearer #{access_token}"]],
]) do |response| ) do |response|
if response.status != 200 if response.status != 200
raise ResponseNotOK.new(response.status), raise ResponseNotOK.new(response.status),
"expected status 200 but got #{response.status} (#{LINKAGE_URL})" "expected status 200 but got #{response.status} (#{LINKAGE_URL})"

View file

@ -1,5 +1,4 @@
require "addressable/uri" require "addressable/uri"
require "async/http/internet/instance"
require "json" require "json"
# The Neopets Media Archive is a service that mirrors images.neopets.com files # The Neopets Media Archive is a service that mirrors images.neopets.com files
@ -11,10 +10,6 @@ require "json"
# long-term archive, not dependent on their services having 100% uptime in # long-term archive, not dependent on their services having 100% uptime in
# order for us to operate. We never discard old files, we just keep going! # order for us to operate. We never discard old files, we just keep going!
module NeopetsMediaArchive module NeopetsMediaArchive
# Share a pool of persistent connections, rather than reconnecting on
# each request. (This library does that automatically!)
INTERNET = Async::HTTP::Internet.instance
ROOT_PATH = Pathname.new(Rails.configuration.neopets_media_archive_root) ROOT_PATH = Pathname.new(Rails.configuration.neopets_media_archive_root)
# Load the file from the given `images.neopets.com` URI. # Load the file from the given `images.neopets.com` URI.
@ -72,9 +67,7 @@ module NeopetsMediaArchive
# We use this in the `swf_assets:manifests:load` task to perform many # We use this in the `swf_assets:manifests:load` task to perform many
# requests in parallel! # requests in parallel!
Sync do Sync do
INTERNET.get(uri, [ DTIRequests.get(uri) do |response|
["User-Agent", Rails.configuration.user_agent_for_neopets],
]) do |response|
if response.status != 200 if response.status != 200
raise ResponseNotOK.new(response.status), raise ResponseNotOK.new(response.status),
"expected status 200 but got #{response.status} (#{uri})" "expected status 200 but got #{response.status} (#{uri})"

View file

@ -1,8 +1,17 @@
require "async" require "async"
require "async/barrier" require "async/barrier"
require "async/http/internet/instance"
module DTIRequests module DTIRequests
class << self class << self
def get(url, headers = [], &block)
Async::HTTP::Internet.get(url, add_headers(headers), &block)
end
def post(url, headers = [], body = nil, &block)
Async::HTTP::Internet.post(url, add_headers(headers), body, &block)
end
def load_many(max_at_once: 10) def load_many(max_at_once: 10)
barrier = Async::Barrier.new barrier = Async::Barrier.new
semaphore = Async::Semaphore.new(max_at_once, parent: barrier) semaphore = Async::Semaphore.new(max_at_once, parent: barrier)
@ -15,5 +24,14 @@ module DTIRequests
barrier.stop # If any subtasks failed, cancel the rest. barrier.stop # If any subtasks failed, cancel the rest.
end end
end end
private
def add_headers(headers)
if headers.none? { |(k, v)| k.downcase == "user-agent" }
headers += [["User-Agent", Rails.configuration.user_agent_for_neopets]]
end
headers
end
end end
end end

View file

@ -1,5 +1,4 @@
require "addressable/template" require "addressable/template"
require "async/http/internet/instance"
namespace "neopets:import" do namespace "neopets:import" do
desc "Import all basic image hashes from the Rainbow Pool, onto PetTypes" desc "Import all basic image hashes from the Rainbow Pool, onto PetTypes"
@ -60,10 +59,6 @@ namespace "neopets:import" do
end end
module RainbowPool module RainbowPool
# Share a pool of persistent connections, rather than reconnecting on
# each request. (This library does that automatically!)
INTERNET = Async::HTTP::Internet.instance
class << self class << self
SPECIES_PAGE_URL_TEMPLATE = Addressable::Template.new( SPECIES_PAGE_URL_TEMPLATE = Addressable::Template.new(
"https://www.neopets.com/pool/all_pb.phtml{?f_species_id}" "https://www.neopets.com/pool/all_pb.phtml{?f_species_id}"
@ -71,10 +66,10 @@ module RainbowPool
def load_hashes_for_species(species_id, neologin) def load_hashes_for_species(species_id, neologin)
Sync do Sync do
url = SPECIES_PAGE_URL_TEMPLATE.expand(f_species_id: species_id) url = SPECIES_PAGE_URL_TEMPLATE.expand(f_species_id: species_id)
INTERNET.get(url, [ DTIRequests.get(
["User-Agent", Rails.configuration.user_agent_for_neopets], url,
["Cookie", "neologin=#{neologin}"], [["Cookie", "neologin=#{neologin}"]],
]) do |response| ) do |response|
if response.status != 200 if response.status != 200
raise "expected status 200 but got #{response.status} (#{url})" raise "expected status 200 but got #{response.status} (#{url})"
end end

View file

@ -9,7 +9,8 @@ RSpec.describe Neopets::NCMall, type: :model do
headers: { headers: {
"Content-Type": "application/x-www-form-urlencoded", "Content-Type": "application/x-www-form-urlencoded",
"X-Requested-With": "XMLHttpRequest", "X-Requested-With": "XMLHttpRequest",
"Cookie": "neologin=STUB_NEOLOGIN" "Cookie": "neologin=STUB_NEOLOGIN",
"User-Agent": Rails.configuration.user_agent_for_neopets,
}, },
body: "mode=getStyles&species=2&tab=1", body: "mode=getStyles&species=2&tab=1",
) )