HTTPS through HTTP proxy - java

I have service which works like a proxy, you can get web pages through it. For example via telnet
GET http://example.com HTTP/1.1
Host: example.com
But if I want download https page I should do the following
GET https://example.com HTTP/1.1
Host: example.com
Https-Header: true
And I want to write scala client for this service using apache http client, using service like a proxy host.
private val DefaultProxy = new HttpHost("service host", port)
private val DefaultClient =
HttpClientBuilder.create().
setProxy(DefaultProxy).
build()
I can successfully download http pages, but when I try to download https pages, apache client makes CONNECT request to the proxy, and it response with error, cause service can operate only with GET requests.
How can I make apache client work with https pages like with http, that's mean send GET request to proxy, not CONNECT?

To download an https webpage in the same way than an http one with telnet you need to establish the ssl/tls connection first:
openssl s_client -connect www.somesite:443
[watch the ssl certificate details scroll by]
GET /index.html HTTP/1.1
Host: www.somesite
Example from https://www.bearfruit.org/2008/04/17/telnet-for-testing-ssl-https-websites/
For scala maybe that can help you : https://github.com/scalaj/scalaj-http
HTTPS is HTTP over SSL/TLS so you need something to establish the SSL/TLS secure tunnel to the website, then you can send your HTTP request.

I find out a solution.
I write custom HttpRoutePlanner which always provide not secure route, and then Apache client work with https link like with http link, there is a HttpRoutePlanner code
private def routePlanner(proxy: HttpHost) = new HttpRoutePlanner() {
def determineRoute(target: HttpHost ,
request: HttpRequest,
context: HttpContext) = {
new HttpRoute(target, null, proxy, false)
}
}

Related

client sent plain HTTP request to HTTPS port while reading client request headers error when connecting to Nginx using java.net.Proxy

I'm using java.net.Proxy to connect to my server via Nginx proxy. The Nginx proxy is SSL enabled. My server URL is https.
When I try the example code below I'm getting 400 error:
client sent plain HTTP request to HTTPS port while reading client request headers
This is probably happening since I cannot specify in the code "https" as the proxy ip address so Nginx proxy thinks its an http request, and generates the error.
It works fine when Nginx proxy SSL is disabled or when I connect directly to my server.
Can this be solved programatically, or only by configuring the Nginx proxy to redirect http requests to https ?
String url = "https://myserver.com";
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("1.2.3.4", 444));
HttpURLConnection con = (HttpURLConnection) (new URL(url).openConnection(proxy));
con.connect();

Java standalone proxy program

I am making a proxy application for a browser. It has to use only the standard libraries. So far, I've managed to create the server. When trying to access a web page from a client, i get the following information:
CONNECT gmail.com:443 HTTP/1.1
User-Agent: Mozilla/5.0 Firefox/49.0
Proxy-Connection: keep-alive
Connection: keep-alive
Host: gmail.com:443
My question is: what to use in order to handle the requests? How to handle a file download?
Once you get that CONNECT command, do what is asked: create the upstream connection, and return the appropriate success/failure response. If the upstream connection was successful, all you have to do now is copy bytes in both directions, simultaneously. The endpoints will take care of all SSL issues, uploads, downloads, etc. You have no further role to play.
The general behaviour of a proxy is as follows:
Receive request from browser
Make a request to the actual server, resolving all redirects if necessary
Get the response from server and passit on to client
I am not getting into complications of changing request/response headers, caching etc.
Now from the above, you are making a SSL connection to gmail.com refer.
The browser is actually sending correct request, in this case you need to implement the handshake and connect to gmail with HTTPS offloading SSL on your side and sending the response received to the browser through the negotiated SSL with the browser.
Suggestion is to use HTTP instead of HTTPS, if this is not a production grader system and try out the concept first

Connection refused in rest assured for HTTPS request

I am trying to test a REST API having an ELB similar to below:
https://systemtest-inventory.com/v1/inventory/getInventory
When I tried the URL with postman chrome, it is giving me valid response.
But when I try to use it in Java program as below:
RestAssured.baseURI="https://systemtest-inventory.com/";
RestAssured.get("v1/inventory/getInventory").then().assertThat().contentType(ContentType.JSON);
It gives this error:
org.apache.http.conn.HttpHostConnectException: Connection to
https://systemtest-inventory.com refused
I am aware that I am using HTTPS and need to have security certificate trusted. However, I am not sure how to do it. Is there any way in Rest assured to test with HTTPS and not HTTP.
You could do something as below for ignoring HTTPS Validation:
given().config(RestAssured.config().sslConfig( new SSLConfig().relaxedHTTPSValidation());
To ignore the HTTPS Connection you can use:
RestAssured.useRelaxedHTTPSValidation();

Configuring SSL with java

I need to sent a POST request on a https url (https://xyz.in). I have a SSL certificate ( cert.cer ) which will be used to send the Request. I donot know how to use that certificate to make a https connection. Can anyone help me who knows how to do it . I am sending request in java

How to test connection to server SSL port via proxy using Apache HttpClient 4.3.4?

I'm trying to validate an SSL connection to an http server through a proxy server. In my case, I have 4 pieces of information which are all supplied by the user, and which I'd like to validate explicitly: target host, target port, proxy host, proxy port. I'd prefer to NOT make an actual HTTP request in order to do this validation, since that requires 2 more pieces of information: a request method, and a path (ie. "GET /"). I'd really like to be able to use the HttpClient library because it supports NTLM proxy auth.
I suppose what I want is to get the response of a CONNECT request sent to the proxy server, as all it requires are the 4 pieces of information I have (plus any proxy creds). However this seems to be an implicit request, the result of which is not available to the library client (unless it returns a 407 status code). Is there some way to trigger the CONNECT request explicitly?
You can use ProxyClient shipped with Apache HttpClient. It does precisely that.

Categories