Skip to content

Commit e78fec7

Browse files
authored
Merge pull request #2961 from pyth-network/fix/headers-invariant
fix: added headers invariant
2 parents 44e489b + 896aede commit e78fec7

File tree

8 files changed

+44
-62
lines changed

8 files changed

+44
-62
lines changed

apps/insights/src/utils/cache.ts renamed to apps/insights/src/cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Cache as ACDCache } from "async-cache-dedupe";
22
import { createCache } from "async-cache-dedupe";
33
import { stringify, parse } from "superjson";
44

5-
import { getRedis } from "../config/server";
5+
import { getRedis } from "./config/server";
66

77
const transformer = {
88
serialize: stringify,

apps/insights/src/get-host.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { headers } from "next/headers";
2+
3+
/**
4+
* Returns the host of the current request.
5+
*
6+
* @returns The host of the current request.
7+
*/
8+
export const getHost = async () => {
9+
const nextHeaders = await headers();
10+
const xfHost = nextHeaders.get("x-forwarded-host")?.split(",")[0]?.trim();
11+
const host = xfHost ?? nextHeaders.get("host") ?? undefined;
12+
if (host === undefined) {
13+
throw new NoHostError();
14+
} else {
15+
const proto =
16+
nextHeaders.get("x-forwarded-proto")?.split(",")[0]?.trim() ??
17+
(host.startsWith("localhost") ? "http" : "https");
18+
19+
return `${proto}://${host}`;
20+
}
21+
};
22+
23+
class NoHostError extends Error {
24+
constructor() {
25+
super(
26+
"Request had neither an `x-forwarded-host` header nor a `host` header",
27+
);
28+
this.name = "NoHostError";
29+
}
30+
}

apps/insights/src/server/pyth.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import { parse } from "superjson";
22
import { z } from "zod";
33

4+
import { DEFAULT_CACHE_TTL } from "../cache";
45
import { VERCEL_REQUEST_HEADERS } from "../config/server";
6+
import { getHost } from "../get-host";
57
import { Cluster, ClusterToName, priceFeedsSchema } from "../services/pyth";
6-
import { absoluteUrl } from "../utils/absolute-url";
7-
import { DEFAULT_CACHE_TTL } from "../utils/cache";
88

99
export async function getPublishersForFeedRequest(
1010
cluster: Cluster,
1111
symbol: string,
1212
) {
13-
const url = await absoluteUrl(
13+
const url = new URL(
1414
`/api/pyth/get-publishers/${encodeURIComponent(symbol)}`,
15+
await getHost(),
1516
);
1617
url.searchParams.set("cluster", ClusterToName[cluster]);
1718

@@ -29,8 +30,9 @@ export async function getFeedsForPublisherRequest(
2930
cluster: Cluster,
3031
publisher: string,
3132
) {
32-
const url = await absoluteUrl(
33+
const url = new URL(
3334
`/api/pyth/get-feeds-for-publisher/${encodeURIComponent(publisher)}`,
35+
await getHost(),
3436
);
3537
url.searchParams.set("cluster", ClusterToName[cluster]);
3638

@@ -46,7 +48,7 @@ export async function getFeedsForPublisherRequest(
4648
}
4749

4850
export const getFeedsRequest = async (cluster: Cluster) => {
49-
const url = await absoluteUrl(`/api/pyth/get-feeds`);
51+
const url = new URL(`/api/pyth/get-feeds`, await getHost());
5052
url.searchParams.set("cluster", ClusterToName[cluster]);
5153
url.searchParams.set("excludePriceComponents", "true");
5254

@@ -72,8 +74,9 @@ export const getFeedForSymbolRequest = async ({
7274
symbol: string;
7375
cluster?: Cluster;
7476
}): Promise<z.infer<typeof priceFeedsSchema.element> | undefined> => {
75-
const url = await absoluteUrl(
77+
const url = new URL(
7678
`/api/pyth/get-feeds/${encodeURIComponent(symbol)}`,
79+
await getHost(),
7780
);
7881
url.searchParams.set("cluster", ClusterToName[cluster]);
7982

apps/insights/src/services/clickhouse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import type { ZodSchema, ZodTypeDef } from "zod";
55
import { z } from "zod";
66

77
import { Cluster, ClusterToName } from "./pyth";
8+
import { redisCache } from "../cache";
89
import { CLICKHOUSE } from "../config/server";
9-
import { redisCache } from "../utils/cache";
1010

1111
const client = createClient(CLICKHOUSE);
1212

apps/insights/src/services/pyth/get-feeds.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Cluster, priceFeedsSchema } from ".";
22
import { getPythMetadataCached } from "./get-metadata";
3-
import { redisCache } from "../../utils/cache";
3+
import { redisCache } from "../../cache";
44

55
const _getFeeds = async (cluster: Cluster) => {
66
const unfilteredData = await getPythMetadataCached(cluster);

apps/insights/src/services/pyth/get-metadata.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { clients, Cluster } from ".";
2-
import { memoryOnlyCache } from "../../utils/cache";
2+
import { memoryOnlyCache } from "../../cache";
33

44
const getPythMetadata = async (cluster: Cluster) => {
55
return clients[cluster].getData();

apps/insights/src/services/pyth/get-publishers-for-cluster.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Cluster } from ".";
22
import { getPythMetadataCached } from "./get-metadata";
3-
import { redisCache } from "../../utils/cache";
3+
import { redisCache } from "../../cache";
44

55
const _getPublishersForCluster = async (cluster: Cluster) => {
66
const data = await getPythMetadataCached(cluster);

apps/insights/src/utils/absolute-url.ts

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)