proxy-detection/src/handlers.ts

156 lines
4.7 KiB
TypeScript

/**
* Route handlers for the proxy detection API
*/
import { FastifyRequest } from 'fastify';
import { extractIPsFromHeaders } from './proxyService';
import { ApiResponse, HealthResponse, DetailedDebugResponse } from './types';
import { config } from './config';
import {
getClientIP,
getFullIPChain,
normalizeHeaders,
extractGeolocation,
extractProxyInfo
} from './utils';
// In-memory cache for results
const cachedResults: ApiResponse[] = [];
/**
* Health check endpoint
*/
export async function healthHandler(): Promise<HealthResponse> {
return {
status: 'healthy',
timestamp: Date.now(),
uptime: process.uptime(),
version: config.api.version
};
}
/**
* Main proxy detection endpoint
*/
export async function mainHandler(request: FastifyRequest): Promise<ApiResponse> {
const headers = request.headers;
const normalizedHeaders = normalizeHeaders(headers);
const result = extractIPsFromHeaders(normalizedHeaders);
const ipInfo = getFullIPChain(request);
// Enhanced response with more context
const response: ApiResponse = {
success: true,
clientIP: ipInfo.clientIP,
ipChain: ipInfo.ipChain,
foundIPs: result.ips,
totalFound: result.ips.length,
headersSources: result.sources,
// Additional context
geolocation: extractGeolocation(normalizedHeaders),
proxy: extractProxyInfo(normalizedHeaders),
allHeaders: normalizedHeaders,
timestamp: Date.now()
};
// Cache management
if (cachedResults.length > config.server.maxCachedResults) {
cachedResults.shift();
}
cachedResults.push(response);
return response;
}
/**
* Random cached result endpoint
*/
export async function randomHandler(): Promise<ApiResponse | { message: string }> {
if (cachedResults.length === 0) {
return { message: 'No data yet' };
}
const randomIndex = Math.floor(Math.random() * cachedResults.length);
return cachedResults[randomIndex];
}
/**
* Detailed debug endpoint with all possible headers
*/
export async function detailedDebugHandler(request: FastifyRequest): Promise<DetailedDebugResponse> {
const headers = request.headers;
return {
allSources: {
// CDN Headers
'cf-connecting-ip': headers['cf-connecting-ip'],
'cf-pseudo-ipv4': headers['cf-pseudo-ipv4'],
'cf-ipcountry': headers['cf-ipcountry'],
'true-client-ip': headers['true-client-ip'],
'x-akamai-edgescape': headers['x-akamai-edgescape'],
'fastly-client-ip': headers['fastly-client-ip'],
// Standard Headers
'x-forwarded-for': headers['x-forwarded-for'],
'x-original-forwarded-for': headers['x-original-forwarded-for'],
'x-client-ip': headers['x-client-ip'],
'x-real-ip': headers['x-real-ip'],
'x-originating-ip': headers['x-originating-ip'],
'x-remote-ip': headers['x-remote-ip'],
'x-remote-addr': headers['x-remote-addr'],
// Load Balancer
'x-cluster-client-ip': headers['x-cluster-client-ip'],
'forwarded': headers['forwarded'],
'x-forwarded': headers['x-forwarded'],
'x-appengine-remote-addr': headers['x-appengine-remote-addr'],
// Cloud Provider
'x-azure-clientip': headers['x-azure-clientip'],
'x-azure-ref': headers['x-azure-ref'],
// Proxy/Firewall
'wl-proxy-client-ip': headers['wl-proxy-client-ip'],
'proxy-client-ip': headers['proxy-client-ip'],
'x-sucuri-clientip': headers['x-sucuri-clientip'],
'incap-client-ip': headers['incap-client-ip'],
// Mobile/Carrier
'x-nokia-msisdn': headers['x-nokia-msisdn'],
'x-up-calling-line-id': headers['x-up-calling-line-id'],
'http_client_ip': headers['http_client_ip'],
'http_x_forwarded_for': headers['http_x_forwarded_for'],
'remote_addr': headers['remote_addr'],
// Alternative
'x-coming-from': headers['x-coming-from'],
'x-forwarded-host': headers['x-forwarded-host'],
'x-host': headers['x-host'],
// Framework defaults
'fastify-ip': request.ip,
'socket-remote': request.socket.remoteAddress
},
detectedClientIP: getClientIP(request),
fastifyIPs: request.ips || [],
// Additional useful info
geolocation: {
'cf-ipcountry': headers['cf-ipcountry'], // Cloudflare country
'cf-ray': headers['cf-ray'], // Cloudflare ray ID
'x-forwarded-proto': headers['x-forwarded-proto'], // Protocol
'x-forwarded-port': headers['x-forwarded-port'], // Port
},
security: {
'x-sucuri-country': headers['x-sucuri-country'],
'x-forwarded-ssl': headers['x-forwarded-ssl'],
'x-url-scheme': headers['x-url-scheme'],
},
timestamp: Date.now()
};
}