Spring WebClient GET request fails with "Moved Permanently. Redirecting to" - spring-webflux

I killed more than one day on this issue and could not understand root cause.
So, I am trying to make simple get request with WebClient from Webflux
WebClient webClient = WebClient.builder().build();
Mono<String> stringMono = webClient.get()
.uri(urlWhichAvailableOnlyUnderVPN)
.retrieve()
.bodyToMono(String.class);
stringMono.subscribe(response -> System.out.println("RESPONSE: " + response));
I am expecting to get xml string from this response but actual output is "RESPONSE: Moved Permanently. Redirecting to another_url"
From browser (google chrome) and Postman I am able to request the urlWhichAvailableOnlyUnderVPN (from code above) and there response is expected xml.
One interesting thing that when I disable my company VPN and try to request URL in browser it responses with "Moved permanently 301". This is strange.
Another interesting thing that the code above is working on my teammate's computer perfectly. We are using almost the same environment and version of Spring Webflux.

You need to configure webclient to follow redirectz
WebClient webClient = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(
HttpClient.create().followRedirect(true)
))
.build();

Related

How can we capture HTTPWebRequest in .net core using Fiddler

I am sending http request to sandbox api which sometimes returns positive response but sometimes it returns bad request with same request data and headers. So I want to debug this request using fiddler during I run the .net core code hitting that api.
But I am not able to find any way to that. Can any one please help me out for the same. I have tried following code to do this:
var requestMessage = GenerateRequestMessage(HttpMethod.Put, uri, query);
requestMessage.Content = new ObjectContent<T>(value, new JsonMediaTypeFormatter(), (MediaTypeHeaderValue)null);
IWebProxy proxy = new WebProxy("127.0.0.1", 8888);
HttpClient.DefaultProxy = proxy;
return _httpClient.SendAsync(requestMessage);
but fiddler is not capturing this api request.

Android WebView SSL handshake failed

I know this question has been asked a lot of times, I tried all solutions, but no one didn't fit my case.
I have news feed in my app, when I clicked on some piece of news - it's open in WebView. Sometimes it gives an error(but still opening site):
E/chromium: [ERROR:ssl_client_socket_impl.cc(959)] handshake failed; returned -1, SSL error code 1, net_error -100
News are loaded by Newscatcher API and OkHttpClient3:
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.build();
Request request = new Request.Builder()
.url("https://free-news.p.rapidapi.com/v1/search?")
.get()
.addHeader("x-rapidapi-key")
.addHeader("x-rapidapi-host")
.build();
Response response = client.newCall(request).execute();
What I've found and tried:
Network Security Configuration - not possible, news sources changes dynamically, I can't include all domains.
Ignore SSL error - not possible, the app will be uploaded to Play Store.
onReceivedSslError and show dialog to make the user responsible for this - I don't think this is a good idea at all.
So, what I can implement in my case to solve this problem?

Which HTTPClient can be used for long running process

I have a requirement where I would need to call a servlet end point.
The servlet does the huge task. It might take about hours to do task.
Keeping all these, I need to build a http client which keeps connection and call this end point. I am not interested in the response. It should just call the endpoint and forget. Which client should i use ?
I tried with apache http client
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
httpclient.start();
HttpGet request = new HttpGet(URL);`
Future<HttpResponse> future = httpclient.execute(request,null);
Does this call the end point of the servlet, because I don't see any logs of the servlet endpoint.
HttpResponse response = future.get();
Is this line required ? As I don't need to capture response.
No, it is not needed. The line:
HttpResponse response = future.get();
blocks your thread until the there is a HTTP response or connection breaks. Check out Future.get() javadoc

IIS 7 Serves GET request correctly to browser but throws timeout exception for API request

I am running a very simple Web application (Asp.Net MVC3) on Win 7 IIS.
I have a very simple HTTP GET API which returns hello world.
Calling:
http://localhost/helloworld
Returns:
Hello World!
This works perfectly over a browser.
But when I write an app which tries to pull this URL using a webclient, I get the following error:
{"Unable to read data from the transport connection: The connection was closed."}
My Code is as follows
WebClient web = new WebClient();
var response = web.DownloadString("http://localhost/helloworld");
My IIS Settings are as follows
What should I be looking at? I have been at this for hours and I have run out of options to try! Any help will be really appreciated!
Thanks.
I suspect it's because WebClient does not send some of the HTTP headers:
A WebClient instance does not send optional HTTP headers by default. If your request requires an optional header, you must add the header to the Headers collection. For example, to retain queries in the response, you must add a user-agent header. Also, servers may return 500 (Internal Server Error) if the user agent header is missing. http://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.80).aspx
Try using HttpWebRequest instead. http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx
I finally figured out what the issue was and instead of it being an IIS specific issue - which I was leaning towards, it turned out to be an issue with the code that I wrote.
Adding details here incase someone else runs into a similar problem.
I had the following method in my code which I was using to send the response of the request as a JSON object.
private void sendJsonResult(string result) {
Response.StatusCode = 200;
Response.Headers.Add("Content-Type", "application/json; charset=utf-8");
Response.Flush();
Response.Write(result);
Response.End();
Response.Close(); // <-- This is the problem statement
}
On digging around a bit, I found out that we should not be doing a Response.Close().
A better explanation of this is here.
Once I removed that line, it started working perfectly - both in my consuming app as well as the web browser, etc.
If you will read the link above, you will clearly understand why we should not be using a Response.Close() - so I will not go into that description. Learnt a new thing today.

Blackberry User-Agent and https Redirect url

I tried to access a HTTPS connection by entering the value in browser, it seems to work fine and redirects me to expected page/output. But when I tried the same using the code, I am unable to get the result. I tried of setting the UserAgent as (Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en-GB) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.141 Mobile Safari/534.1+). But no luck. I am getting trusted connection alert, when i click continue i get response code 302.How can i implement secure connection certificate to disable trusted connection alert.
I am used to httpsconnection to open url it returns the response code 302.Again i checked with
if (rc == HttpConnection.HTTP_TEMP_REDIRECT
|| rc == HttpConnection.HTTP_MOVED_TEMP
|| rc == HttpConnection.HTTP_MOVED_PERM) {
String location = conn.getHeaderField("location").trim();
System.out.println("location========"+location);
try {
Url = location;
newhttpConn = (HttpConnection) Connector.open(Url, Connector.READ_WRITE);
newhttpConn.setRequestMethod(HttpConnection.POST);
newhttpConn.setRequestProperty("User-Agent",
System.getProperty("browser.useragent"));
} catch (Exception e) {
System.out.println( e.toString());
}
But no use i am getting same 302 from redirect url.
EDITED:
Also please give some ideas to get the functions equivalent to HTTPClient to be work in HTTPSConnection. How can i get those functionalities. If there is no possibility to use Httpclient in blackberry then how can i utilize Blackberry https connection equivalent to Httpcleint (or) to get the automatic redirect using HTTPS Connection?
When connector.open(url) excutes i am getting like this
SSL:->CH
SSL:<-SH
SSL:<-SC
SSL:<-SHD
TLS:->CKE
SSL:->CCS
TLS:->F
TLS:<-F
in output console then wrong response displayed.
I am getting trusted connection alert, when i click continue i get response code 302.
This is a fully expected behaviour.
302 means the requested resource is on some other URI. In other words server instructs you to execute a redirect. You should investigate connection headers and in the one named "Location" you will find a new URI to continue with. Close/finalize you current connection and start a new one for the just got redirect URI.
UPDATE:
Usually good servers respond with HTTP 302 after a successful POST. This is a known Post/Redirect/Get pattern to prevent users from posting the same data twise on browser page refresh (user may press F5 in a desktop browser). So if the page you are accessing via POST is designed for usual browsers, then this may just mean your POST was successful and you don't need to execute a redirecting request. At least, if you need the response for some result evaluation then don't redirect using a POST, this time use a GET.