LittleProxy is a high performance HTTP proxy written in Java atop Trustin Lee's excellent Netty event-based networking library

Related tags

HTTP LittleProxy
Overview

Build Status

LittleProxy is a high performance HTTP proxy written in Java atop Trustin Lee's excellent Netty event-based networking library. It's quite stable, performs well, and is easy to integrate into your projects.

One option is to clone LittleProxy and run it from the command line. This is as simple as:

$ git clone git://github.com/adamfisk/LittleProxy.git
$ cd LittleProxy
$ ./run.bash

You can embed LittleProxy in your own projects through Maven with the following:

    
   
        
    
     org.littleshoot
    
        
    
     littleproxy
    
        
    
     1.1.2
    
    
   

Once you've included LittleProxy, you can start the server with the following:

HttpProxyServer server =
    DefaultHttpProxyServer.bootstrap()
        .withPort(8080)
        .start();

To intercept and manipulate HTTPS traffic, LittleProxy uses a man-in-the-middle (MITM) manager. LittleProxy's default implementation (SelfSignedMitmManager) has a fairly limited feature set. For greater control over certificate impersonation, browser trust, the TLS handshake, and more, use a the LittleProxy-compatible MITM extension:

  • LittleProxy-mitm - A LittleProxy MITM extension that aims to support every Java platform including Android
  • mitm - A LittleProxy MITM extension that supports elliptic curve cryptography and custom trust stores

To filter HTTP traffic, you can add request and response filters using a HttpFiltersSource(Adapter), for example:

HttpProxyServer server =
    DefaultHttpProxyServer.bootstrap()
        .withPort(8080)
        .withFiltersSource(new HttpFiltersSourceAdapter() {
            public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) {
                return new HttpFiltersAdapter(originalRequest) {
                    @Override
                    public HttpResponse clientToProxyRequest(HttpObject httpObject) {
                        // TODO: implement your filtering here
                        return null;
                    }

                    @Override
                    public HttpObject serverToProxyResponse(HttpObject httpObject) {
                        // TODO: implement your filtering here
                        return httpObject;
                    }
                };
            }
        })
        .start();

Please refer to the Javadoc of org.littleshoot.proxy.HttpFilters to see the methods you can use.

To enable aggregator and inflater you have to return a value greater than 0 in your HttpFiltersSource#get(Request/Response)BufferSizeInBytes() methods. This provides to you a `FullHttp(Request/Response)' with the complete content in your filter uncompressed. Otherwise you have to handle the chunks yourself.

    @Override
    public int getMaximumResponseBufferSizeInBytes() {
        return 10 * 1024 * 1024;
    }

This size limit applies to every connection. To disable aggregating by URL at *.iso or *dmg files for example, you can return in your filters source a filter like this:

return new HttpFiltersAdapter(originalRequest, serverCtx) {
    @Override
    public void proxyToServerConnectionSucceeded(ChannelHandlerContext serverCtx) {
        ChannelPipeline pipeline = serverCtx.pipeline();
        if (pipeline.get("inflater") != null) {
            pipeline.remove("inflater");
        }
        if (pipeline.get("aggregator") != null) {
            pipeline.remove("aggregator");
        }
        super.proxyToServerConnectionSucceeded(serverCtx);
    }
};

This enables huge downloads in an application, which regular handles size limited FullHttpResponses to modify its content, HTML for example.

A proxy server like LittleProxy contains always a web server, too. If you get an URI without scheme, host and port in originalRequest it's a direct request to your proxy. You can return a HttpFilters implementation which answers responses with HTML content or redirects in clientToProxyRequest like this:

public class AnswerRequestFilter extends HttpFiltersAdapter {
	private final String answer;

	public AnswerRequestFilter(HttpRequest originalRequest, String answer) {
		super(originalRequest, null);
		this.answer = answer;
	}

	@Override
	public HttpResponse clientToProxyRequest(HttpObject httpObject) {
		ByteBuf buffer = Unpooled.wrappedBuffer(answer.getBytes("UTF-8"));
		HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buffer);
		HttpHeaders.setContentLength(response, buffer.readableBytes());
		HttpHeaders.setHeader(response, HttpHeaders.Names.CONTENT_TYPE, "text/html");
		return response;
	}
}

On answering a redirect, you should add a Connection: close header, to avoid blocking behavior:

		HttpHeaders.setHeader(response, Names.CONNECTION, Values.CLOSE);

With this trick, you can implement an UI to your application very easy.

If you want to create additional proxy servers with similar configuration but listening on different ports, you can clone an existing server. The cloned servers will share event loops to reduce resource usage and when one clone is stopped, all are stopped.

existingServer.clone().withPort(8081).start()

For examples of configuring logging, see src/test/resources/log4j.xml.

If you have questions, please visit our Google Group here:

https://groups.google.com/forum/#!forum/littleproxy

To subscribe, send an E-Mail to mailto:[email protected]. Simply answering, don't clicking the button, bypasses Googles registration process. You will become a member.

Benchmarking instructions and results can be found here.

Acknowledgments

Many thanks to The Measurement Factory for the use of Co-Advisor for HTTP standards compliance testing.

Comments
  • Enhance the mitm feature -- forge certificates dynamically

    Enhance the mitm feature -- forge certificates dynamically

    Hi, all This pull request have enhanced the mitm feature, able to forge certificates dynamically. Could you kindly have a look and merge it.

    lubin Thanks & Best Regards

    opened by dawnbreaks 30
  • Is it possible to bind littleproxy to a specific interface?

    Is it possible to bind littleproxy to a specific interface?

    I have two or more physical network interfaces, connected to the internet and i would like to create a proxy for each of them. Is this possible with littleproxy? (using linux)

    opened by PatrickHuetter 30
  • MITM With SSL?

    MITM With SSL?

    I'm not sure if this is a bug or I'm just missing something, I'm assuming the latter. Trying to run the Mitm test, nothing happens on SSL connections. The browser just spins forever waiting for a response and I see no error or other activity coming from the proxy. I'm coming to LittleProxy from my own transparent proxy, and first thing I see missing is the creation, installation or any use of a root CA by which the proxy can spoof certs for the sake of intercepting SSL. Am I just missing some code or documentation? Thanks in advance.

    opened by TechnikEmpire 24
  • Error in connection close handling logic

    Error in connection close handling logic

    There's an issue where the browser/client will open a single connection to LittleProxy and send multiple requests through it. That results in multiple connections to external servers. Then, when one of those servers indicates the end of an HTTP response body through closing the connection we don't necessarily close the connection to the browser because in some cases there are still other outgoing connections associated with that single browser/client connection.

    I'm not sure what the optimal solution is to this problem. Maybe if those other connections have all sent responses we can close it? Maybe we simply wait for all those responses before the close?

    opened by adamfisk 24
  • MITM and Chained proxy support

    MITM and Chained proxy support

    PR for MITM + Chained proxy support. Basic scenarios work. Raising an early PR to get feedback and review comments.

    PS : This is my first PR to any project. :) Please do let me know if there's anything to be modified/changed.

    opened by MediumOne 19
  • Add back Man in the Middle Support

    Add back Man in the Middle Support

    Support for man in the middle (MITM) on https connections was lost as part of the 1.0 refactor. We should add this back in.

    There are two levels to which we can take it:

    • Rudimentary (as before). Proxy simply uses its own self-signed certificate, which does not match the domain of the server that the client requested. Typical clients will not accept this certificate.
    • Full. Proxy actually acts as a certificate authority and issues certificates on the fly. As long as the client trusts LittleProxy's cert, the client will then implicitly trust the issued certs. See here for an explanation of how this is done by mitmproxy.
    opened by oxtoacart 19
  • Implement a Maven plugin

    Implement a Maven plugin

    Hi,

    I was wondering: how hard would it be to implement a Maven plugin for this? It would be quite useful for running certain tests in projects/code that deal(s) with proxies. Is there a basic programmatic example one could have a look at in order to implement this?

    Kind regards,

    Martin

    opened by carlspring 18
  • Issue 285: Support for chained SOCKS proxies

    Issue 285: Support for chained SOCKS proxies

    This change adds support for two additional types of chained upstream proxies: SOCKS4 and SOCKS5 (in addition to the existing HTTP proxy support). See related issue here: https://github.com/adamfisk/LittleProxy/issues/285

    Users can take advantage of the new SOCKS support by setting some new fields in ChainedProxy / ChainedProxyAdapter:

    • There is a new enum called ChainedProxyType with possible values { HTTP, SOCKS4, SOCKS5 }
    • Username and/or password can be specified for the upstream SOCKS server. SOCKS4 supports username; SOCKS5 supports username and password

    Overall the changes were fairly minor because I was able to take advantage of the built-in SOCKS client support in Netty 4.1. However, in order to use those new classes I had to change the default Netty version from 4.0 to 4.1 in pom.xml.

    All existing unit tests are passing, and wrote new tests for SOCKS4 and SOCKS5 which take advantage of the SOCKS server in the netty-example module.

    opened by jbaldassari 16
  • HTTPS and offline cache working with LittleProxy

    HTTPS and offline cache working with LittleProxy

    It's derived from the OWASP Zed Attack Proxy Project, which is licensed under the Apache License, Version 2.0. The certificate authority is created lazily with Bouncy Castle. The key store type is PKCS12, which has to be implemented by every vendor. The server certificates won't be cached, but the connection is already cached. It lacks upstream certificate validation(!) and a proper exception handling.

    opened by ganskef 16
  • NTLM support for chained proxy

    NTLM support for chained proxy

    This is code proposal for LittleProxy to support preemptive NTLM authentication to a chained proxy. In the class extending ChainedProxyAdapter, just set an NTLM handler to enable this feature.

    setNtlmMessageHandler(new NtlmHandlerImpl(new JcifsNtlmProvider("myuser", "mypass")));

    I have used http://jcifs.samba.org/ as default provider to generate NTLM messages, but any provider can be plugged in.

    opened by dparmar 14
  • LEAK: ByteBuf.release() was not called before it's garbage-collected

    LEAK: ByteBuf.release() was not called before it's garbage-collected

    When I use littleProxy,I did not add much code, I just make getMaximumRequestBufferSizeInBytes and getMaximumResponseBufferSizeInBytes return 1010241024 in HttpFiltersSource, it occur ByteBuf release error,when I make them return 0, there is no error. How to handle please? the bootstrap is as fowllows

    HttpProxyServerBootstrap bootstrap = DefaultHttpProxyServer
                    .bootstrapFromFile("./littleproxy.properties")
                    .withPort(port)
                    .withAllowLocalOnly(false)
                    .withFiltersSource(new HttpFiltersSource() {
                        @Override
                        public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) {
                            return HttpFiltersAdapter.NOOP_FILTER;
                        }
    
                        @Override
                        public int getMaximumRequestBufferSizeInBytes() {
                            return 10*1024*1024;
                        }
    
                        @Override
                        public int getMaximumResponseBufferSizeInBytes() {
                            return 10*1024*1024;
                        }
                    });
    

    the error is as below

    188115 2016-07-18 11:27:25,118 ERROR [LittleProxy-0-ClientToProxyWorker-3] util.ResourceLeakDetector (Slf4JLogger.java:171).error() - LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
    Recent access records: 5
    #5:
        io.netty.buffer.AdvancedLeakAwareCompositeByteBuf.release(AdvancedLeakAwareCompositeByteBuf.java:791)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpMessage.release(HttpObjectAggregator.java:390)
        io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:59)
        io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:91)
        io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:619)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:676)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:612)
        io.netty.channel.ChannelOutboundHandlerAdapter.write(ChannelOutboundHandlerAdapter.java:104)
        org.littleshoot.proxy.impl.ProxyConnection$RequestWrittenMonitor.write(ProxyConnection.java:788)
        io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:619)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:676)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:612)
        io.netty.handler.timeout.IdleStateHandler.write(IdleStateHandler.java:284)
        io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:619)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:676)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:612)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:593)
        io.netty.channel.DefaultChannelPipeline.write(DefaultChannelPipeline.java:1055)
        io.netty.channel.AbstractChannel.write(AbstractChannel.java:234)
        org.littleshoot.proxy.impl.ProxyConnection.writeHttp(ProxyConnection.java:248)
        org.littleshoot.proxy.impl.ProxyToServerConnection.writeHttp(ProxyToServerConnection.java:358)
        org.littleshoot.proxy.impl.ProxyConnection.doWrite(ProxyConnection.java:232)
        org.littleshoot.proxy.impl.ProxyToServerConnection.write(ProxyToServerConnection.java:344)
        org.littleshoot.proxy.impl.ProxyToServerConnection.connectionSucceeded(ProxyToServerConnection.java:934)
        org.littleshoot.proxy.impl.ConnectionFlow.succeed(ConnectionFlow.java:168)
        org.littleshoot.proxy.impl.ConnectionFlow.advance(ConnectionFlow.java:88)
        org.littleshoot.proxy.impl.ConnectionFlowStep.onSuccess(ConnectionFlowStep.java:83)
        org.littleshoot.proxy.impl.ConnectionFlow$2.operationComplete(ConnectionFlow.java:149)
        io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:683)
        io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:604)
        io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:564)
        io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:407)
        io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:82)
        io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:255)
        io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:290)
        io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:545)
        io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:485)
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:399)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:371)
        io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
        java.lang.Thread.run(Thread.java:745)
    #4:
        io.netty.buffer.AdvancedLeakAwareCompositeByteBuf.retain(AdvancedLeakAwareCompositeByteBuf.java:775)
        io.netty.buffer.AdvancedLeakAwareCompositeByteBuf.retain(AdvancedLeakAwareCompositeByteBuf.java:34)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpMessage.retain(HttpObjectAggregator.java:378)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpRequest.retain(HttpObjectAggregator.java:437)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpRequest.retain(HttpObjectAggregator.java:405)
        org.littleshoot.proxy.impl.ProxyToServerConnection.write(ProxyToServerConnection.java:315)
        org.littleshoot.proxy.impl.ProxyToServerConnection.connectionSucceeded(ProxyToServerConnection.java:934)
        org.littleshoot.proxy.impl.ConnectionFlow.succeed(ConnectionFlow.java:168)
        org.littleshoot.proxy.impl.ConnectionFlow.advance(ConnectionFlow.java:88)
        org.littleshoot.proxy.impl.ConnectionFlowStep.onSuccess(ConnectionFlowStep.java:83)
        org.littleshoot.proxy.impl.ConnectionFlow$2.operationComplete(ConnectionFlow.java:149)
        io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:683)
        io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:604)
        io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:564)
        io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:407)
        io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:82)
        io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:255)
        io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:290)
        io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:545)
        io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:485)
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:399)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:371)
        io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
        java.lang.Thread.run(Thread.java:745)
    #3:
        io.netty.buffer.AdvancedLeakAwareCompositeByteBuf.release(AdvancedLeakAwareCompositeByteBuf.java:791)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpMessage.release(HttpObjectAggregator.java:390)
        io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:59)
        io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:112)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        org.littleshoot.proxy.impl.ProxyConnection$RequestReadMonitor.channelRead(ProxyConnection.java:715)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:277)
        io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:264)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        org.littleshoot.proxy.impl.ProxyConnection$BytesReadMonitor.channelRead(ProxyConnection.java:692)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:962)
        io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
        io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528)
        io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:485)
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:399)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:371)
        io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
        java.lang.Thread.run(Thread.java:745)
    #2:
        io.netty.buffer.AdvancedLeakAwareCompositeByteBuf.retain(AdvancedLeakAwareCompositeByteBuf.java:775)
        io.netty.buffer.AdvancedLeakAwareCompositeByteBuf.retain(AdvancedLeakAwareCompositeByteBuf.java:34)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpMessage.retain(HttpObjectAggregator.java:378)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpRequest.retain(HttpObjectAggregator.java:437)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpRequest.retain(HttpObjectAggregator.java:405)
        org.littleshoot.proxy.impl.ProxyToServerConnection.write(ProxyToServerConnection.java:315)
        org.littleshoot.proxy.impl.ProxyToServerConnection.write(ProxyToServerConnection.java:306)
        org.littleshoot.proxy.impl.ClientToProxyConnection.doReadHTTPInitial(ClientToProxyConnection.java:335)
        org.littleshoot.proxy.impl.ClientToProxyConnection.readHTTPInitial(ClientToProxyConnection.java:191)
        org.littleshoot.proxy.impl.ClientToProxyConnection.readHTTPInitial(ClientToProxyConnection.java:80)
        org.littleshoot.proxy.impl.ProxyConnection.readHTTP(ProxyConnection.java:135)
        org.littleshoot.proxy.impl.ProxyConnection.read(ProxyConnection.java:120)
        org.littleshoot.proxy.impl.ProxyConnection.channelRead0(ProxyConnection.java:587)
        io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        org.littleshoot.proxy.impl.ProxyConnection$RequestReadMonitor.channelRead(ProxyConnection.java:715)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:277)
        io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:264)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        org.littleshoot.proxy.impl.ProxyConnection$BytesReadMonitor.channelRead(ProxyConnection.java:692)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:962)
        io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
        io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528)
        io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:485)
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:399)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:371)
        io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
        java.lang.Thread.run(Thread.java:745)
    #1:
        io.netty.buffer.AdvancedLeakAwareCompositeByteBuf.copy(AdvancedLeakAwareCompositeByteBuf.java:631)
        io.netty.handler.codec.http.HttpObjectAggregator$AggregatedFullHttpRequest.copy(HttpObjectAggregator.java:413)
        org.littleshoot.proxy.impl.ClientToProxyConnection.copy(ClientToProxyConnection.java:1011)
        org.littleshoot.proxy.impl.ClientToProxyConnection.doReadHTTPInitial(ClientToProxyConnection.java:215)
        org.littleshoot.proxy.impl.ClientToProxyConnection.readHTTPInitial(ClientToProxyConnection.java:191)
        org.littleshoot.proxy.impl.ClientToProxyConnection.readHTTPInitial(ClientToProxyConnection.java:80)
        org.littleshoot.proxy.impl.ProxyConnection.readHTTP(ProxyConnection.java:135)
        org.littleshoot.proxy.impl.ProxyConnection.read(ProxyConnection.java:120)
        org.littleshoot.proxy.impl.ProxyConnection.channelRead0(ProxyConnection.java:587)
        io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        org.littleshoot.proxy.impl.ProxyConnection$RequestReadMonitor.channelRead(ProxyConnection.java:715)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:277)
        io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:264)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        org.littleshoot.proxy.impl.ProxyConnection$BytesReadMonitor.channelRead(ProxyConnection.java:692)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:962)
        io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
        io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528)
        io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:485)
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:399)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:371)
        io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
        java.lang.Thread.run(Thread.java:745)
    Created at:
        io.netty.buffer.AbstractByteBufAllocator.compositeDirectBuffer(AbstractByteBufAllocator.java:213)
        io.netty.buffer.AbstractByteBufAllocator.compositeBuffer(AbstractByteBufAllocator.java:191)
        io.netty.handler.codec.http.HttpObjectAggregator.decode(HttpObjectAggregator.java:184)
        io.netty.handler.codec.http.HttpObjectAggregator.decode(HttpObjectAggregator.java:57)
        io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        org.littleshoot.proxy.impl.ProxyConnection$RequestReadMonitor.channelRead(ProxyConnection.java:715)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:277)
        io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:264)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
        org.littleshoot.proxy.impl.ProxyConnection$BytesReadMonitor.channelRead(ProxyConnection.java:692)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
        io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:962)
        io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
        io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528)
        io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:485)
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:399)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:371)
        io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
        java.lang.Thread.run(Thread.java:745)
    
    opened by zhangshihai1232 13
  • Can't read content of Request

    Can't read content of Request

    I'm trying to develop code that can filter requests, modify them, etc. The Proxy intercepts requests correctly and is able to display the correct Uri for example. However, I cannot read the contents of the http package. In fact, the request.content (). ReadableBytes () function returns 0.

    HttpProxyServer server = DefaultHttpProxyServer.bootstrap() .withAddress(new InetSocketAddress("localhost", 8080)) .withTransparent(true) .withFiltersSource(new HttpFiltersSourceAdapter() { @Override public int getMaximumRequestBufferSizeInBytes() { return 512 * 1024; } @Override public int getMaximumResponseBufferSizeInBytes() { return 50 * 1024 * 1024; } public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) { return new HttpFiltersAdapter(originalRequest) { @Override public HttpResponse clientToProxyRequest(HttpObject httpObject) { FullHttpRequest request = (FullHttpRequest) httpObject; CompositeByteBuf contentBuf = (CompositeByteBuf) request.content(); System.out.println(request.getUri()); System.out.println(request.content().readableBytes());

    So, why request.content().readableBytes() returns always 0 ?

    opened by niccocorsa94 0
  • Avoid using plaintext Keystore password in source code

    Avoid using plaintext Keystore password in source code

    Vulnerability Location: In fileLittleProxy/src/main/java/org/littleshoot/proxy/extras/SelfSignedSslEngineSource.java, keyStore.load is invoked with a hard-coded password in line 109

    Security Impact: Keystore password should not be kept in the source code. The source code can be widely shared in an enterprise environment, and is certainly shared in open source. The product transmits or stores authentication credentials, but it uses an insecure way that is susceptible to unauthorized interception and/or retrieval.

    suggestions: To be managed safely, passwords or secret keys should be stored in separate configuration files or keystores. The Keystore password is better to load from the locally set files instead of directly set in the code.

    Useful link: https://cwe.mitre.org/data/definitions/321.html https://cwe.mitre.org/data/definitions/522.html https://www.baeldung.com/java-keystore

    Please share with us your opinions/comments if there is any: Is the bug report helpful?

    opened by YYTVicky 2
  • Any one maintain this project?

    Any one maintain this project?

     @Override
        public ChannelFuture writeHttp(HttpObject httpObject) {
            if (httpObject instanceof HttpRequest) {
                startReadTimeoutHandler();
                HttpRequest httpRequest = (HttpRequest)httpObject;
                currentHttpRequest = httpRequest;
            }
            ChannelFuture channelFuture = super.writeHttp(httpObject);
            channelFuture.addListener(new ChannelFutureListener() {
    
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                     if (!future.isSuccess()) {
                            LOG.error("Attempted to writeHttp to origin server failed, The cause is: ", future.cause());
                            timedOut();
                        }
                }
            });
            return channelFuture;
        }
    

    when the channel is disconnected in write, can retry?

    opened by linking12 0
  • Customized TrustManager bypasses certificate verification

    Customized TrustManager bypasses certificate verification

    Vulnerability Description:

    We found a security vulnerability in file LittleProxy/src/main/java/org/littleshoot/proxy/extras/SelfSignedSslEngineSource.java. The customized TrustManger (at Line 125) allows all certificates to pass the verification.

    Security Impact:

    The checkClientTrusted and checkServerTrusted methods are expected to implement the certificate validation logic. Bypassing it could allow man-in-the-middle attacks.

    Useful Resources:

    https://cwe.mitre.org/data/definitions/295.html

    https://developer.android.com/training/articles/security-ssl

    Solution we suggest:

    Do not customize the TrustManger or specify the certificate validation logic instead of allowing all certificates. See here to securely allow self-signed certificates and other common cases.

    Please share with us your opinions/comments if there is any:

    Is the bug report helpful?

    opened by GraceXiaoYa 0
  • How to update request body with a longer content?

    How to update request body with a longer content?

    hello guys,

    how to update httpContent in filters ?

    my code is here, it works if i change the capacity shorter or stay unchanged, but not works if i change it bigger. what's the problem?

    `

    private class MyHttpFiltersSourceAdapter extends HttpFiltersSourceAdapter {
        @Override
        public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext clientCtx) {
            Log.v(TAG, "request: " + originalRequest.hashCode() + " uri: " + originalRequest.getUri() + ", method: " + originalRequest.getMethod());
            if (originalRequest.getMethod() == HttpMethod.GET
                    || originalRequest.getMethod() == HttpMethod.HEAD
                    || originalRequest.getMethod() == HttpMethod.POST) {
                return new MyHttpFilter(originalRequest, clientCtx);
            }
        }
    }
    
    private class MyHttpFilter extends HttpFiltersAdapter {
        @Override
        public HttpResponse clientToProxyRequest(HttpObject httpObject) {
            if (httpObject instanceof LastHttpContent) {
                LastHttpContent httpContent = (LastHttpContent) httpObject;
                ByteBuf byteBuffer = httpContent.content().slice();
                byte[] body = new byte[byteBuffer.readableBytes()];
                byteBuffer.getBytes(0, body);
                String contentString = new String(body, io.netty.util.CharsetUtil.UTF_8);
                String newBody = "111111111111111111";
                try {
                    int idx = byteBufIdx(byteBuffer, 0);
                    if (idx >= 0) {
                        int writerIndex = byteBuffer.writerIndex();
                        int readSize = byteBuffer.readableBytes();
                        Log.d(TAG, "before update readable " + readSize + " writeidx " + byteBuffer.writerIndex());
    
                        ByteBuf bodyContent = Unpooled.copiedBuffer(newBody, io.netty.util.CharsetUtil.UTF_8);
                        int newSize = bodyContent.readableBytes();
    
                        // tricky: use internal api to avoid length check
                        int innerCap = byteBuffer.unwrap().capacity();
                        byteBuffer.unwrap().capacity(innerCap + newSize - readSize);
                        byteBuffer.unwrap().setBytes(idx, bodyContent, 0, newSize);
    
                        // update outter index&cap
                        int cc = byteBufAdjustCapacity(byteBuffer, newSize - readSize);
                        byteBuffer.writerIndex(writerIndex - readSize + newSize);
                        Log.d(TAG, "update post content " + contentString + " to " + newBody + " new cap " + cc + " writeidx " + byteBuffer.writerIndex());
    
                        byte[] readout = new byte[byteBuffer.readableBytes()];
    
                        byteBuffer.getBytes(byteBuffer.readerIndex(), readout);
                        Log.d(TAG, "bytebuf: " + new String(readout, io.netty.util.CharsetUtil.UTF_8));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
            }
        }
    }
    

    `

    opened by wangqunfeng 0
Releases(littleproxy-1.1.2)
  • littleproxy-1.1.2(Mar 5, 2017)

    LittleProxy 1.1.2 has been released! This is another maintenance release with updated dependencies and a few important bug fixes:

    • Fix memory leak on initial requests
    • Fix duplicate 502 Gateway Timeout responses
    • Fix Transfer-Encoding manipulation for sdch encoding
    • Close connection and return a 400 after invalid client requests
    • Add allowRequestsToOriginServer bootstrap option for reverse proxies

    Thanks to everyone who contributed code, tested fixes, and logged issues, including:

    @danielkyu @luleyl @Schnutzel @fomin-vyacheslav-main @mjallday @weakie @zhangshihai1232

    And thanks to all our other testers and contributors!

    -The LittleProxy Team

    Source code(tar.gz)
    Source code(zip)
    littleproxy-1.1.2-littleproxy-shade.jar(7.74 MB)
  • littleproxy-1.1.1(Dec 27, 2016)

    LittleProxy 1.1.1 has been released! This is a maintenance release that fixes a few bugs and updates important dependencies:

    • Java 7: LittleProxy now requires Java 7+
    • Update to netty 4.0.42 (fixes several bugs and memory leaks in netty)
    • Fix ChannelPipeline initialization order
    • Allow configuring max initial line length, header size, and chunk size
    • Fix hang when receiving invalid responses from server
    • Removed dependencies on commons-codec and commons-io

    Thanks to everyone who contributed code, tested fixes, and logged issues, including:

    @ganskef @MediumOne @adamfisk @BraisGabin @techpavan @myleshorton @zboralski

    And thanks to all our other contributors!

    -The LittleProxy team

    Source code(tar.gz)
    Source code(zip)
    littleproxy-1.1.1-littleproxy-shade.jar(7.49 MB)
  • littleproxy-1.1.0(May 28, 2016)

    LittleProxy 1.1.0 has been released! This release contains a handful of changes and defect fixes since the previous 1.1.0-beta2 release.

    • Allow modifying connection timeout after proxy is started
    • Automatically retry connections without SNI if Java aborts the connection due to the "unrecognized_name" TLS alert
    • Defect fixes for issues affecting filter reuse and HTTP 101 WebSocket upgrade responses
    • Breaking Change for MitmManager implementations: MitmManager.clientSslEngineFor() now receives the HttpRequest, to assist with impersonation.
    • Java 6: This is the last release we plan to support and test against Java 6. Java 7 will be the baseline for future releases.

    Thanks to everyone who has contributed and tested LittleProxy, including:

    @ganskef @MediumOne @javiersigler @myleshorton @oxtoacart @adamfisk

    And thanks to all our other contributors!

    -The LittleProxy team

    Source code(tar.gz)
    Source code(zip)
    littleproxy-1.1.0-littleproxy-shade.jar(7.81 MB)
  • littleproxy-1.1.0-beta2(Mar 26, 2016)

    LittleProxy 1.1.0-beta2 has been released! It is now available in Maven Central. This release brings some exiciting enhancements, including:

    • MITM support with chained proxies
    • Several Android fixes
    • Thread pool configuration and minor performance improvements
    • Proxy Authentication enhancements
    • Documentation updates, bugfixes, and performance improvements

    Thank you to everyone who contributing time and effort developing and testing for this release. An especially big thank you to our contributors:

    @ganskef @MediumOne @adamfisk @andrewtaylor

    Happy Proxying!

    -LittleProxy contributors

    Source code(tar.gz)
    Source code(zip)
    littleproxy-1.1.0-beta2-littleproxy-shade.jar(7.81 MB)
  • littleproxy-1.1.0-beta1(Aug 28, 2015)

    We are pleased to announce the release of LittleProxy 1.1.0-beta1! This is the first beta release in the 1.1.0 and comes with a significant number of bug fixes and new features. The release is available in Central and on the github releases page.

    Special thanks to all the developers and testers who contributed to this release, as well as all those who reported issues and provided invaluable design reviews, comments, and advice.

    @adamfisk @oxtoacart @ganskef @detro @andrewtaylor @schoeffm @robUx4 @jekh @myleshorton

    My apologies to anyone who was accidentally overlooked; please let us know and we will rectify the omission.

    We're planning to greatly increase the frequency of future releases, so please continue report issues on github.

    Thank you again!

    --LittleProxy contributors

    Source code(tar.gz)
    Source code(zip)
    littleproxy-1.1.0-beta1-littleproxy-shade.jar(7.40 MB)
A simple script i made that generate a valid http(s) proxy in json format with its geo-location info

Gev Proxy Generator GPG is a simple PHP script that generate a proxy using free services on the web, the proxy is HTTP(s) and it generate it in json f

gev 1 Nov 15, 2021
Event-driven, streaming HTTP client and server implementation for ReactPHP

HTTP Event-driven, streaming HTTP client and server implementation for ReactPHP. This HTTP library provides re-usable implementations for an HTTP clie

ReactPHP 640 Dec 29, 2022
Declarative HTTP Clients using Guzzle HTTP Library and PHP 8 Attributes

Waffler How to install? $ composer require waffler/waffler This package requires PHP 8 or above. How to test? $ composer phpunit Quick start For our e

Waffler 3 Aug 26, 2022
Requests - a HTTP library written in PHP, for human beings

Requests is a HTTP library written in PHP, for human beings. It is roughly based on the API from the excellent Requests Python library. Requests is ISC Licensed (similar to the new BSD license) and has no dependencies, except for PHP 5.6+.

WordPress 3.5k Jan 6, 2023
Express.php is a new HTTP - Server especially made for RESTful APIs written in PHP.

express.php Express.php is a new HTTP - Server especially made for RESTful APIs written in PHP. Features Fast The Library is handles requests fast and

null 5 Aug 19, 2022
Spike is a fast reverse proxy built on top of ReactPHP that helps to expose your local services to the internet.

Spike is a fast reverse proxy built on top of ReactPHP that helps to expose your local services to the internet. 简体中文 Installation Install via compose

Tao 649 Dec 26, 2022
Proxy method and property interactions in PHP. ⚡️

Proxy method and property interactions in PHP. Provides a Proxy class that can be used to intercept method calls, property access and updates. Support

Ryan Chandler 4 Mar 28, 2022
Plug & Play [CURL + Composer Optional], Proxy as a Service, Multi-tenant, Multi-Threaded, with Cache & Article Spinner

?? .yxorP The SAAS(y), Multitenancy & Augmenting Web Proxy Guzzler is a 100% SAAS(y) plug-and-play (PHP CURL+Composer are Optional) solution that leverages SAAS architecture to provide multi-tenancy, multiple threads, caching, and an article spinner service.

4D/ҵ.com Dashboards 12 Nov 17, 2022
HTTP header kit for PHP 7.1+ (incl. PHP 8) based on PSR-7

HTTP header kit for PHP 7.1+ (incl. PHP 8) based on PSR-7 Installation composer require sunrise/http-header-kit How to use? HTTP Header Collection Mor

Sunrise // PHP 63 Dec 31, 2022
TusPHP - 🚀a HTTP based protocol for resumable file uploads.

tus is a HTTP based protocol for resumable file uploads. Resumable means you can carry on where you left off without re-uploading whole data again in case of any interruptions. An interruption may happen willingly if the user wants to pause, or by accident in case of a network issue or server outage.

Ankit Pokhrel 1.3k Dec 28, 2022
Async HTTP/1.1+2 client for PHP based on Amp.

This package provides an asynchronous HTTP client for PHP based on Amp. Its API simplifies standards-compliant HTTP resource traversal and RESTful web

AMPHP 641 Dec 19, 2022
Simple HTTP cURL client for PHP 7.1+ based on PSR-18

Simple HTTP cURL client for PHP 7.1+ based on PSR-18 Installation composer require sunrise/http-client-curl QuickStart composer require sunrise/http-f

Sunrise // PHP 15 Sep 5, 2022
Requests for PHP is a humble HTTP request library. It simplifies how you interact with other sites and takes away all your worries.

Requests for PHP Requests is a HTTP library written in PHP, for human beings. It is roughly based on the API from the excellent Requests Python librar

null 3.5k Dec 31, 2022
Requests for PHP is a humble HTTP request library. It simplifies how you interact with other sites and takes away all your worries.

Requests for PHP Requests is a HTTP library written in PHP, for human beings. It is roughly based on the API from the excellent Requests Python librar

null 3.5k Dec 31, 2022
Unirest in PHP: Simplified, lightweight HTTP client library.

Unirest for PHP Unirest is a set of lightweight HTTP libraries available in multiple languages, built and maintained by Mashape, who also maintain the

Kong 1.3k Dec 28, 2022
The Library for HTTP Status Codes, Messages and Exception

This is a PHP library for HTTP status codes, messages and error exception. Within the library, HTTP status codes are available in classes based on the section they belong to. Click this link for more information.

Sabuhi Alizada 5 Sep 14, 2022
Guzzle, an extensible PHP HTTP client

Guzzle, PHP HTTP client Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services. Simple interf

Guzzle 22.3k Jan 2, 2023
A Chainable, REST Friendly, PHP HTTP Client. A sane alternative to cURL.

Httpful Httpful is a simple Http Client library for PHP 7.2+. There is an emphasis of readability, simplicity, and flexibility – basically provide the

Nate Good 1.7k Dec 21, 2022
PHP's lightweight HTTP client

Buzz - Scripted HTTP browser Buzz is a lightweight (<1000 lines of code) PHP 7.1 library for issuing HTTP requests. The library includes three clients

Kris Wallsmith 1.9k Jan 4, 2023