All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.reactivex.netty.examples.http.proxy.ProxyServer Maven / Gradle / Ivy

There is a newer version: 0.5.3
Show newest version
/*
 * Copyright 2016 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.reactivex.netty.examples.http.proxy;

import io.netty.buffer.ByteBuf;
import io.netty.handler.logging.LogLevel;
import io.reactivex.netty.examples.ExamplesEnvironment;
import io.reactivex.netty.protocol.http.client.HttpClient;
import io.reactivex.netty.protocol.http.client.HttpClientRequest;
import io.reactivex.netty.protocol.http.server.HttpServer;

import java.util.Iterator;
import java.util.Map.Entry;

import static rx.Observable.*;

/**
 * An example to demonstrate how to write a simple HTTP proxy.
 *
 * The intent here is NOT to prescribe how to write a fully functional proxy, which would otherwise require
 * setting appropriate request headers, do appropriate routing on the origin endpoints, etc. Instead, it is to
 * demonstrate how to write a server that forwards the received request, as is to another server using an RxNetty
 * client.
 *
 * This example starts an embedded target server, which is a simple HTTP server that returns a response with HTTP
 * status of 200 and a content of "Hello World!" for every request it recieves. The proxy server then forwards all
 * received requests to this target server preserving all the request and response headers as well as content. It
 * adds an additional response header "X-Proxied-By" with a value "RxNetty" to demonstrate that the response is a
 * proxied response.
 */
public final class ProxyServer {

    public static void main(final String[] args) {

        ExamplesEnvironment env = ExamplesEnvironment.newEnvironment(ProxyServer.class);

        /*Starts an embedded target server using an ephemeral port.*/
        int targetServerPort = startTargetServer();

        /*Create a new HTTP client pointing to the target server.*/
        final HttpClient targetClient = HttpClient.newClient("127.0.0.1", targetServerPort);

        HttpServer server;

        /*Starts a new HTTP server on an ephemeral port which acts as a proxy to the target server started above.*/
        server = HttpServer.newServer()
                           .enableWireLogging("proxy-server", LogLevel.DEBUG)
                           .start((serverReq, serverResp) -> {
                                      /*
                                       * Create a new HTTP request for the target server, using the method and URI from
                                       * the server request.
                                       */
                                      HttpClientRequest clientReq =
                                              targetClient.createRequest(serverReq.getHttpMethod(), serverReq.getUri());

                                      /*Copy all server request headers to the client request*/
                                      Iterator> serverReqHeaders = serverReq.headerIterator();
                                      while (serverReqHeaders.hasNext()) {
                                          Entry next = serverReqHeaders.next();
                                          /*Since, the client request is copied for each mutation,
                                          use the latest instance*/
                                          clientReq = clientReq.setHeader(next.getKey(), next.getValue());
                                      }

                                      return clientReq.writeContent(serverReq.getContent())
                                              .flatMap(clientResp -> {
                                                  /*Iterator for the client response headers.*/
                                                  Iterator> clientRespHeaders =
                                                          clientResp.headerIterator();

                                                  /*Copy all client response headers to the server response.*/
                                                  while (clientRespHeaders.hasNext()) {
                                                      Entry next = clientRespHeaders.next();
                                                      serverResp.setHeader(next.getKey(), next.getValue());
                                                  }

                                                  /*Add a demo header to indicate proxied response!*/
                                                  serverResp.setHeader("X-Proxied-By", "RxNetty");

                                                  /*Write the client response content to server response.*/
                                                  return serverResp.write(clientResp.getContent());
                                              });
                                  }
                           );

        /*Wait for shutdown if not called from the client (passed an arg)*/
        if (env.shouldWaitForShutdown(args)) {
            server.awaitShutdown();
        }

        /*If not waiting for shutdown, assign the ephemeral port used to a field so that it can be read and used by
        the caller, if any.*/
        env.registerServerAddress(server.getServerAddress());
    }

    private static int startTargetServer() {
        /*Start a hello world server using an ephemeral port*/
        return HttpServer.newServer()
                         .start((req, resp) -> resp.writeString(just("HelloWorld!")))
                         .getServerPort();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy