{"id":15029199,"url":"https://github.com/mitre/http-proxy-servlet","last_synced_at":"2025-05-15T07:07:10.241Z","repository":{"id":3132578,"uuid":"4160806","full_name":"mitre/HTTP-Proxy-Servlet","owner":"mitre","description":"Smiley's HTTP Proxy implemented as a Java servlet","archived":false,"fork":false,"pushed_at":"2024-07-05T12:55:33.000Z","size":366,"stargazers_count":1477,"open_issues_count":74,"forks_count":558,"subscribers_count":87,"default_branch":"master","last_synced_at":"2025-05-15T07:07:04.685Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitre.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-04-27T17:43:25.000Z","updated_at":"2025-05-08T09:05:25.000Z","dependencies_parsed_at":"2023-07-05T19:33:54.023Z","dependency_job_id":"7160f1f7-b3d9-42db-a14b-b8efc91997d1","html_url":"https://github.com/mitre/HTTP-Proxy-Servlet","commit_stats":{"total_commits":217,"total_committers":49,"mean_commits":4.428571428571429,"dds":0.6175115207373272,"last_synced_commit":"531709323746f4a3a281a7c76875096bef560b3a"},"previous_names":["dsmiley/http-proxy-servlet"],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitre%2FHTTP-Proxy-Servlet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitre%2FHTTP-Proxy-Servlet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitre%2FHTTP-Proxy-Servlet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitre%2FHTTP-Proxy-Servlet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitre","download_url":"https://codeload.github.com/mitre/HTTP-Proxy-Servlet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254292042,"owners_count":22046426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T20:09:56.877Z","updated_at":"2025-05-15T07:07:05.210Z","avatar_url":"https://github.com/mitre.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Smiley's HTTP Proxy Servlet\n===========================\n\nThis is an HTTP Proxy (aka gateway) in the form of a Java servlet.  An HTTP proxy is useful for AJAX applications to communicate with web accessible services on hosts other than where the web application is hosted.  It's a _reverse proxy_, and not really a _forwarding proxy_ albeit the template form of the servlet may blur that line.\n\nThis is hardly the first proxy, so why did I write it and thus why might you use it?\n\n * It's simple -- a single source file implementation\n * It's tested -- have confidence it works ![Build Status](https://github.com/mitre/HTTP-Proxy-Servlet/actions/workflows/maven.yml/badge.svg)\n * It's securable -- via Java EE web.xml or via a servlet filter such as [Spring-Security]([http://static.springsource.org/spring-security/site/)\n * It's extendable -- via simple class extension\n * It's embeddable -- into your Java web application making testing your app easier\n\nI have seen many quick'n'dirty proxies posted in source form on the web such as in a blog.\nI've found such proxies to support a limited HTTP subset, such as only a GET request, or to suffer other implementation problems such as performance issues or URL escaping bugs.\nDisappointed at the situation, I set out to create a simple one that works well and that is well tested so I know it works.\nI suggest you use a well tested proxy instead of something non-tested that is perhaps better described as a proof-of-concept.\n\nIf you need something more sophisticated than there are some alternatives listed at the bottom of this page.\n\nThis proxy depends on [Apache HttpClient](http://hc.apache.org/httpcomponents-client-ga/), which offers another point of extension for this proxy.\nAt some point I may write an alternative that uses the JDK and thus doesn't have any dependencies, which is desirable.\nIn the meantime, you'll have to add the jar files for this and its dependencies:\n\n     +- org.apache.httpcomponents:httpclient:jar:4.5.13:compile\n        +- org.apache.httpcomponents:httpcore:jar:4.4.13:compile\n        |  +- commons-logging:commons-logging:jar:1.2:compile\n        |  \\- commons-codec:commons-codec:jar:1.11:compile\n\nThis proxy supports HttpClient 4.5, and newer version too.\nIf you need to support _older_ HttpClient versions:\n* use 1.8 version of this proxy for HttpClient versions 4.1 and 4.2\n* use 1.12 version of this proxy for HttpClient versions 4.3 and 4.4\n\nAs of version 2.0 of the proxy, the proxy switched to the `jakarta servlet-api`, while nonetheless retaining support for the `javax servlet-api` version for those that need it.  To use that, specify the `javax` classifier on the dependency declaration as follows:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.mitre.dsmiley.httpproxy\u003c/groupId\u003e\n    \u003cartifactId\u003esmiley-http-proxy-servlet\u003c/artifactId\u003e\n    \u003cversion\u003e${smiley-http-proxy-servlet.version}\u003c/version\u003e\n    \u003cclassifier\u003ejavax\u003c/classifier\u003e\n\u003c/dependency\u003e\n```\n\nAs of version 1.5 of the proxy, there is the ability to parameterize your proxy URL, allowing you to use\nthe same web.xml servlet specification for multiple target servers. It follows the\n[URI Template RFC, Level 1](http://tools.ietf.org/html/rfc6570). Special query\nparameters (see the examples below) sent from the client to the ProxyServlet will\nmap to the matching URL template, replacing arguments in the proxy's targetUri as\nspecified in the web.xml.  To use this, you must use a subclass of the base servlet.\nIMPORTANT! The template substitutions must be placed in the query string, even when using\nHTTP POST. Other application parameters can be in your POSTed url-encoded-form string; just not\nproxyArgs.\n\nSee [CHANGES.md](CHANGES.md) for a history of changes.\n\nBuild \u0026 Installation\n------------\n\nSimply build the jar using \"mvn package\" at the command line.\nThe jar is built to \"target/smiley-http-proxy-servlet-VERSION.jar\".\nYou don't have to build the jar if you aren't modifying the code, since released\nversions are deployed to maven-central.  If you are using maven then you can\nadd this to your dependencies in your pom like so:\n(Note: the version below is not necessarily the latest.)\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.mitre.dsmiley.httpproxy\u003c/groupId\u003e\n    \u003cartifactId\u003esmiley-http-proxy-servlet\u003c/artifactId\u003e\n    \u003cversion\u003e1.12.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\nIvy and other dependency managers can be used as well.\n\n\nConfiguration\n-------------\n### Parameters\n\nThe following is a list of parameters that can be configured\n\n+ log: A boolean parameter name to enable logging of input and target URLs to the servlet log.\n+ forwardip: A boolean parameter name to enable forwarding of the client IP\n+ preserveHost: A boolean parameter name to keep HOST parameter as-is  \n+ preserveCookies: A boolean parameter name to keep COOKIES as-is\n+ preserveCookiePath: A boolean parameter name to keep cookie path unchanged in Set-Cookie server response header\n+ http.protocol.handle-redirects: A boolean parameter name to have auto-handle redirects\n+ http.socket.timeout: A integer parameter name to set the socket connection timeout (millis)\n+ http.read.timeout: A integer parameter name to set the socket read timeout (millis)\n+ http.connectionrequest.timeout: A integer parameter name to set the connection request timeout (millis)\n+ http.maxConnections: A integer parameter name to set max connection number\n+ useSystemProperties: A boolean parameter whether to use JVM-defined system properties to configure various networking aspects.\n+ targetUri: The parameter name for the target (destination) URI to proxy to.\n\n\n### Servlet\n\nHere's an example excerpt of a web.xml file to communicate to a Solr server:\n\n```xml\n\u003cservlet\u003e\n  \u003cservlet-name\u003esolr\u003c/servlet-name\u003e\n  \u003cservlet-class\u003eorg.mitre.dsmiley.httpproxy.ProxyServlet\u003c/servlet-class\u003e\n  \u003cinit-param\u003e\n    \u003cparam-name\u003etargetUri\u003c/param-name\u003e\n    \u003cparam-value\u003ehttp://solrserver:8983/solr\u003c/param-value\u003e\n  \u003c/init-param\u003e\n  \u003cinit-param\u003e\n    \u003cparam-name\u003elog\u003c/param-name\u003e\n    \u003cparam-value\u003etrue\u003c/param-value\u003e\n  \u003c/init-param\u003e\n\u003c/servlet\u003e\n\u003cservlet-mapping\u003e\n  \u003cservlet-name\u003esolr\u003c/servlet-name\u003e\n  \u003curl-pattern\u003e/solr/*\u003c/url-pattern\u003e\n\u003c/servlet-mapping\u003e\n```\n\nHere's an example with a parameterized proxy URL matching query parameters\n_subHost, _port, and _path such as\n\"http://mywebapp/cluster/subpath?_subHost=namenode\u0026_port=8080\u0026_path=monitor\". Note the different\nproxy servlet class. The leading underscore is not mandatory but it's good to differentiate\nthem from the normal query parameters in case of a conflict.:\n\n```xml\n\u003cservlet\u003e\n  \u003cservlet-name\u003eclusterProxy\u003c/servlet-name\u003e\n  \u003cservlet-class\u003eorg.mitre.dsmiley.httpproxy.URITemplateProxyServlet\u003c/servlet-class\u003e\n  \u003cinit-param\u003e\n    \u003cparam-name\u003etargetUri\u003c/param-name\u003e\n    \u003cparam-value\u003ehttp://{_subHost}.behindfirewall.mycompany.com:{_port}/{_path}\u003c/param-value\u003e\n  \u003c/init-param\u003e\n  \u003cinit-param\u003e\n    \u003cparam-name\u003elog\u003c/param-name\u003e\n    \u003cparam-value\u003etrue\u003c/param-value\u003e\n  \u003c/init-param\u003e\n\u003c/servlet\u003e\n\n\u003cservlet-mapping\u003e\n  \u003cservlet-name\u003eclusterProxy\u003c/servlet-name\u003e\n  \u003curl-pattern\u003e/mywebapp/cluster/*\u003c/url-pattern\u003e\n\u003c/servlet-mapping\u003e\n```\n\n### SpringMVC\n\nIf you are using **SpringMVC**, then an alternative is to use its\n[ServletWrappingController](http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/web/servlet/mvc/ServletWrappingController.html)\nso that you can configure this servlet via Spring, which is supremely flexible, instead of having to modify your web.xml. However, note that some\ncustomization may be needed to divide the URL at the proxied portion; see [Issue #15](https://github.com/mitre/HTTP-Proxy-Servlet/issues/15).\n\n### Spring Boot\n\nIf you are using **Spring Boot**, then consider this basic configuration:\n\n```java\n@Configuration\npublic class SolrProxyServletConfiguration implements EnvironmentAware {\n\n  @Bean\n  public ServletRegistrationBean servletRegistrationBean() {\n    ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ProxyServlet(), propertyResolver.getProperty(\"servlet_url\"));\n    servletRegistrationBean.addInitParameter(ProxyServlet.P_TARGET_URI, propertyResolver.getProperty(\"target_url\"));\n    servletRegistrationBean.addInitParameter(ProxyServlet.P_LOG, propertyResolver.getProperty(\"logging_enabled\", \"false\"));\n    return servletRegistrationBean;\n  }\n\n  private RelaxedPropertyResolver propertyResolver;\n\n  @Override\n  public void setEnvironment(Environment environment) {\n    this.propertyResolver = new RelaxedPropertyResolver(environment, \"proxy.solr.\");\n  }\n}\n```\nif you use Spring Boot 2.x,you can try this:\n```java\n@Configuration\npublic class SolrProxyServletConfiguration implements EnvironmentAware {\n\n    @Bean\n    public ServletRegistrationBean servletRegistrationBean() {\n        Properties properties= (Properties) bindResult.get();\n        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ProxyServlet(), properties.getProperty(\"servlet_url\"));\n        servletRegistrationBean.addInitParameter(ProxyServlet.P_TARGET_URI, properties.getProperty(\"target_url\"));\n        servletRegistrationBean.addInitParameter(ProxyServlet.P_LOG, properties.getProperty(\"logging_enabled\", \"false\"));\n        return servletRegistrationBean;\n    }\n\n    private BindResult bindResult;\n\n    @Override\n    public void setEnvironment(Environment environment) {\n        Iterable sources = ConfigurationPropertySources.get(environment);\n        Binder binder = new Binder(sources);\n        BindResult bindResult = binder.bind(\"proxy.solr\", Properties.class);\n        this.bindResult = bindResult;\n    }\n}\n```\n\nand properties in `application.yml`:\n\n```yaml\nproxy:\n    solr:\n        servlet_url: /solr/*\n        target_url: http://solrserver:8983/solr\n```\n\nIt may be the case that Spring Boot (or Spring MVC) is consuming the servlet input stream before the servlet gets it, which is a problem.  \nSee [Issue #83](https://github.com/mitre/HTTP-Proxy-Servlet/issues/83#issuecomment-307216795) RE disabling `FilterRegistrationBean`.\n\n### Dropwizard\n\nAddition of Smiley's proxy to Dropwizard is very straightforward.   \n\nAdd a new property in the Dropwizard app `.yml` file\n\n```\ntargetUri: http://foo.com/api  \n```\n\nCreate a new configuration property\n\n```java\n    @NotEmpty\n    private String targetUri = \"\";\n\n    @JsonProperty(\"targetUri\")\n    public String getTargetUri() {\n        return targetUri;\n    }  \n```\n\nThen register Smiley's proxy servlet with Jetty through the Dropwizard service's App `run()` method.\n\n```java\n@Override\n    public void run(final ShepherdServiceConfiguration configuration,\n        final Environment environment) {\n\n        environment.getApplicationContext()\n            .addServlet(\"org.mitre.dsmiley.httpproxy.ProxyServlet\", \"foo/*\")\n            .setInitParameter(\"targetUri\", configuration.getTargetUri());  \n```\n\nAlternatives\n-------------\nThis servlet is intentionally simple and limited in scope.  As such it may not meet your needs, so consider looking at these alternatives:\n* Jetty's ProxyServlet: https://www.eclipse.org/jetty/javadoc/jetty-9/org/eclipse/jetty/proxy/ProxyServlet.html  This is perhaps the closest competitor (simple, limited scope, no dependencies), and may very well already be on your classpath.\n* Netflix's Zuul: https://github.com/Netflix/zuul\n* Charon: https://github.com/mkopylec/charon-spring-boot-starter\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitre%2Fhttp-proxy-servlet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitre%2Fhttp-proxy-servlet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitre%2Fhttp-proxy-servlet/lists"}