FastProxy Main Components Explained: InProxy vs OutProxy Architecture

FastProxy separates reverse-proxy logic into two distinct components—InProxy for handling incoming client requests and OutProxy for forwarding traffic to downstream services—unified by a shared server core written in Go.

FastProxy is a lightweight, extensible HTTP/HTTPS reverse-proxy framework written in Go. The kingson4wu/fast_proxy repository implements a modular architecture that separates traffic handling concerns through its two primary components: InProxy and OutProxy. Understanding how these components interact is essential for deploying and extending the proxy system effectively.

FastProxy Architecture Overview

The FastProxy codebase organizes functionality into three logical layers:

  • InProxy (github.com/Kingson4Wu/fast_proxy/inproxy): Accepts client requests, performs optional preprocessing such as decryption or authentication, and forwards them to target services.
  • OutProxy (github.com/Kingson4Wu/fast_proxy/outproxy): Acts as a forward-proxy for downstream services, handling connection pooling, TLS termination, and response manipulation.
  • Shared Core (github.com/Kingson4Wu/fast_proxy/common): Provides unified server infrastructure, configuration loading (YAML/Apollo), logging via Zap, service discovery, and rate-limiting utilities.

Both components rely on the common/server package for the underlying HTTP server implementation, which supports both standard net/http and high-performance fasthttp modes.

InProxy: The Entry Point for Client Traffic

The InProxy component serves as the primary entry point for external client requests. Located in the inproxy package, it handles request acceptance, preprocessing, and forwarding to internal services.

Bootstrap and Configuration

The NewServer function in inproxy/inproxy.go initializes the component by reading configuration and building a reusable HTTP client:

// inproxy/inproxy.go:23-26
func NewServer(c inconfig.Config, opts ...server.Option) {
    inconfig.Read(c)
    proxy.BuildClient(c)
    p := server.NewServer(c, zap.DefaultLogger(), requestProxy)

According to the FastProxy source code, inconfig.Read loads configuration from YAML or Apollo, while proxy.BuildClient constructs the HTTP client with appropriate timeouts and transport settings.

Request Processing Pipeline

Every incoming request flows through the requestProxy handler, which delegates to the internal proxy implementation:

// inproxy/inproxy.go:18-21
func requestProxy(res http.ResponseWriter, req *http.Request) {
    proxy.DoProxy(res, req)
}

The actual forwarding logic resides in inproxy/internal/proxy/httpclientProxy.go. The proxy.DoProxy function constructs the outbound request, applies optional encryption through inproxy/internal/encrypt/encrypt.go, executes rate-limiting checks via inproxy/internal/limiter/limitManager.go, and forwards the request using the shared client pool.

Graceful Shutdown

InProxy registers cleanup hooks to ensure resource释放 on termination:

// inproxy/inproxy.go:27-30
p.RegisterOnShutdown(func() {
    server.GetLogger().Info("clean resources on shutdown...")
})

OutProxy: The Forward Proxy for Downstream Services

The OutProxy component operates as a forward proxy that downstream services use to reach external destinations. It manages connection reuse, TLS handshake optimization, and response transformation.

Initialization Workflow

Similar to InProxy, OutProxy begins with NewServer in outproxy/outproxy.go:

// outproxy/outproxy.go:29-32
func NewServer(c outconfig.Config, opts ...server.Option) {
    outconfig.Read(c)
    proxy.BuildClient(c)
    p := server.NewServer(c, zap.DefaultLogger(), requestProxy)

The outconfig.Read function handles OutProxy-specific configuration, while proxy.BuildClient constructs the client pool optimized for high-throughput forwarding scenarios.

Forward Proxy Mechanism

OutProxy uses a distinct proxy type to handle forwarding. The requestProxy function retrieves the forward proxy implementation and delegates handling:

// outproxy/outproxy.go:18-26
func requestProxy(res http.ResponseWriter, req *http.Request) {
    proxyType := proxy.FORWARD
    p := proxy.GetProxy(proxyType)
    if p != nil { p.Handle(res, req) }
}

The concrete implementation resides in outproxy/internal/proxy/httpclientProxy.go. Unlike InProxy's direct forwarding approach, OutProxy explicitly uses proxy.GetProxy(proxy.FORWARD) to obtain a handler that manages connection persistence and optional request/response transformation.

Resource Cleanup

OutProxy includes explicit cleanup for the proxy pool during shutdown:

// outproxy/outproxy.go:33-36
p.RegisterOnShutdown(func() {
    server.GetLogger().Info("clean resources on shutdown...")
    proxy.Close()
})

The proxy.Close() call ensures that all idle connections in the pool are closed properly, preventing connection leaks when the server terminates.

Shared Server Core

Both InProxy and OutProxy depend on common/server/server.go for infrastructure concerns. The shared core provides:

  • Configuration-driven listeners: Support for custom ports, TLS certificates, and fasthttp mode toggling.
  • Graceful shutdown: Signal handling with configurable timeouts via RegisterOnShutdown.
  • Observability: Optional pprof endpoints for runtime profiling.

The entry point server.NewServer creates the underlying http.Server instance and wires the provided handler (either inproxy.requestProxy or outproxy.requestProxy) to the request multiplexer.

Running FastProxy Components

Starting an InProxy Instance

To run the InProxy component, initialize the configuration and start the server:

package main

import (
    "github.com/Kingson4Wu/fast_proxy/inproxy"
    "github.com/Kingson4Wu/fast_proxy/inproxy/inconfig"
)

func main() {
    var cfg inconfig.Config
    cfg = inconfig.NewYAMLConfig("examples/inproxy/config.yaml")
    inproxy.NewServer(cfg)
}

This loads examples/inproxy/config.yaml, builds the HTTP client according to the configuration, and starts listening on the configured port with graceful shutdown enabled.

Starting an OutProxy Instance

To deploy the OutProxy component:

package main

import (
    "github.com/Kingson4Wu/fast_proxy/outproxy"
    "github.com/Kingson4Wu/fast_proxy/outproxy/outconfig"
)

func main() {
    cfg := outconfig.NewYAMLConfig("examples/outproxy/config.yaml")
    outproxy.NewServer(cfg)
}

The OutProxy now acts as a forward proxy that downstream services can route through to reach external endpoints, leveraging the connection pooling and TLS management implemented in outproxy/internal/proxy/httpclientProxy.go.

Summary

  • InProxy handles incoming client traffic in inproxy/inproxy.go, preprocesses requests, and forwards them to target services using proxy.DoProxy.
  • OutProxy operates as a forward proxy in outproxy/outproxy.go, managing outbound connections through proxy.GetProxy(proxy.FORWARD).
  • Both components share the Server Core (common/server/server.go) for HTTP server abstraction and graceful shutdown capabilities.
  • Configuration is split by component (inconfig vs outconfig) but follows a unified pattern supporting YAML and Apollo.
  • The architecture supports extensibility through internal packages for encryption (inproxy/internal/encrypt), rate-limiting (inproxy/internal/limiter), and service discovery (common/servicediscovery).

Frequently Asked Questions

What is the difference between InProxy and OutProxy in FastProxy?

InProxy functions as a reverse proxy entry point that accepts external HTTP/HTTPS requests, optionally decrypts or authenticates them, and forwards them to internal services. OutProxy acts as a forward proxy that internal services use to make outbound requests to external destinations, handling connection pooling and TLS termination. InProxy uses proxy.DoProxy for direct forwarding, while OutProxy uses proxy.GetProxy(proxy.FORWARD) to retrieve a specialized forward handler.

How does FastProxy handle configuration for both components?

FastProxy uses separate configuration packages—inproxy/inconfig for InProxy and outproxy/outconfig for OutProxy—each implementing Read and BuildClient functions. Both support YAML files and Apollo configuration centers. The NewServer functions in inproxy.go and outproxy.go consume these configuration objects to build customized HTTP clients and server instances.

Can InProxy and OutProxy run independently?

Yes, InProxy and OutProxy are designed to operate as independent binaries. Each has its own main package entry point and configuration schema. They share only the common utilities (common/server, common/logger, etc.) but do not require each other to function, allowing you to deploy only the component needed for your architecture.

What shared utilities do FastProxy components use?

Both components utilize packages under github.com/Kingson4Wu/fast_proxy/common, including structured logging via common/logger/zap, service discovery via common/servicediscovery, and the unified server abstraction in common/server. Additionally, InProxy-specific features like encryption (inproxy/internal/encrypt) and rate-limiting (inproxy/internal/limiter) can be optionally enabled without affecting the OutProxy component.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →