I'd like to test (via automated test) how server (and all proxies in-the-middle) responds to a PUT request without body and Content-Length header.
Similar to what curl does
curl -XPUT http://example.com
with Apache HTTP client (4.5.13)
But it looks like it always adds Content-Length header if I specify no body.
Is there any way to do that with Apache HTTP client?
Already tried (no luck)
final HttpPut request = new HttpPut(url);
request.removeHeaders("Content-Length");
Use a request interceptor to modify requests generated by the standard protocol processor
CloseableHttpClient httpClient = HttpClients.custom()
.addInterceptorLast((HttpRequestInterceptor) (request, context) ->
request.removeHeaders(HttpHeaders.CONTENT_LENGTH))
.build();
HttpPut httpPut = new HttpPut("http://httpbin.org/put");
httpClient.execute(httpPut, response -> {
EntityUtils.consume(response.getEntity());
return null;
});
POST request to server using java URLConnnection
I need to send a POST request with the two parameters below:
param1=value1
param2=value2
And also I need to send a file.
In the case of Apache these 2 two(sending params and file) things are handled like below
post.setQueryString(queryString) // queryString is url encoded for eg: param1=value1¶m2=value2
post.setRequestEntity(entity) // entity is constructed using file input stream with corresponding format
Please let me know if you have anything related to this problem.
Please note: When I try using Google Chrome REST client plug-in, I am getting the response as below (tried with all request content-types)
UNSUPPORTED FILE FORMAT: 'multipart/form-data' is not a supported content-type
Response code is 400.
Try this API from Apache to send request internally with POST method.
The below is the sample Code to use API
List<org.apache.http.NameValuePair> list =new ArrayList<org.apache.http.NameValuePair>();
HttpPost postMethod = new HttpPost("http://yoururl/ProjectName");
list.add(new BasicNameValuePair("param1", "param1 Value")) ;
postMethod.setEntity(new UrlEncodedFormEntity(list));
HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(postMethod);
InputStream is = response.getEntity().getContent();
is it possible to pass some data in HTTP Header, while redirecting a request from one server to another.
Here is my scenario,
I have one generic filter, via which every request is passing.
Now, based on some condition, I'm redirecting the request to some different server using the API objHttpServletResponse.sendRedirect(strURL).
But, the issue is, when I'm setting some data in response header like objHttpServletResponse.setHeader("Key", "Value"); That's not available in the redirected server.
So, my questions are,
1. Is there any way to pass some data in header while redirecting a request?
2. If not, what are the other possible ways to send some data while redirecting a request?
Please Note: few other ways, like
using URL parameters:
objHttpServletResponse.sendRedirect(strURL+"?param="+ strParamValue);
or
using session:
HttpSession session = httpRequest.getSession();
session.setAttribute("Key", "Value");
is not what I'm expecting.
The headers you set are written to the response that gets sent to the client, along with a Location header and a status code. See Redirecting a request using servlets and the "setHeader" method not working
The client is then supposed to send an identical request to the URL you specified in the Location header. Identical to the request it sent to you.
You want the browser to send a header you specify along with the redirected request. Have you considered adding a (domain) Cookie header? Some googling leads me to believe that cookies set in a redirect response will get picked up by most browsers. See http://blog.dubbelboer.com/2012/11/25/302-cookie.html
Please have a look at Apache HttpClient.
This example adds several parameters to the post request :
String url = "https://selfsolve.apple.com/wcResults.do";
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
// add header
post.setHeader("User-Agent", USER_AGENT);
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("sn", "C02G8416DRJM"));
urlParameters.add(new BasicNameValuePair("cn", ""));
urlParameters.add(new BasicNameValuePair("locale", ""));
urlParameters.add(new BasicNameValuePair("caller", ""));
urlParameters.add(new BasicNameValuePair("num", "12345"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
System.out.println("Response Code : "
+ response.getStatusLine().getStatusCode());
The problem is that the redirect() method of the response initiates a new request altogether, thereby loosing the attributes that were set before redirecting. Luckily there is a fluent way of solving the problem still.
response.setHeader("Key", "Value");
request.getRequestDispatcher("redirecturl").forward(request, response);
Then in your destination you can do
response.getHeaders("key")
You can use JS redirect, i.e. instead of calling sendRedirect return HTML page with embedded javascript that will do redirect setting headers you need.
However, using GET parameters is really the best solution. If you have concerns about users altering parameters manually - use MAC code to protect parameters.See
Message authentication code
In simplest form, ?p1=1&p2=2&mac={mac value}, where {mac value} = md5('MY_SECRET_KEY' + 'p1=1&p2=2').
Receiving side can recalculate MAC and compare it with provided one. Since external users can not know 'MY_SECRET_KEY', they will not be able to make valid MAC.
Have you checked the HTTP request/response from/to server? You can use a number of plugins on chrome or firefox to check that. You would be able to see if value is being passed from your server to another server or not
Also retrieve the header using httpResponse.getHeader("Key"); not using request.getHeader("key"). One of my colleague was facing same issue some days back, he was using request to fetch header values
For example the default user agent could be set like:
client.getParams().setParameter(CoreProtocolPNames.USER_AGENT, someName);
But how to set the "Accept" header?
HttpClient 4.3 now allows configuring a collection of default headers on the client itself:
Header header = new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/json");
List<Header> headers = Lists.newArrayList(header);
HttpClient client = HttpClients.custom().setDefaultHeaders(headers).build();
HttpUriRequest request = RequestBuilder.get().setUri(SAMPLE_URL).build();
client.execute(request);
Now, all requests executed by that client will be send with the default headers.
Hope that helps.
I am using Apache Commons HttpClient v3.1. All my requests are having correct (default) HTTP version in the request line i.e HTTP/1.1 except for 1 request.
Following Post request gets the requestline as HTTP/0.9:
server : port/cas/v1/tickets/TGT-1-sUqenNbqUzvkGSWW25lcbaJc0OEcJ6wg5DOj3XDMSwoIBf6s7i-cas-1
Body: service=*
I debugged through the http client code and saw the requestline is set to HTTP/1.1 but on the server I see the request coming as HTTP/0.9.
I tried to set the HTTP version explicitly using the HttpMethodParams but that does not help.
Does anyone have an idea what could be wrong?
HttpClient client = new HttpClient();
HostConfiguration hc = client.getHostConfiguration();
hc.setHost(new URI(url, false));
PostMethod method = new PostMethod();
method.setURI(new URI(url, false));
method.getParams().setUriCharset("UTF-8");
method.getParams().setHttpElementCharset("UTF-8");
method.getParams().setContentCharset("UTF-8");
method.getParams().setVersion(HttpVersion.HTTP_1_1);
method.addParameter("service", URLEncoder.encode(service, "UTF-8"));
method.setPath(contextPath + "/tickets/" + tgt);
String respBody = null;
int statusCode = client.executeMethod(method);
respBody = method.getResponseBodyAsString();
Thanks Joachim Sauer. I was able to figure out the problem.
I was using Webscarab as web proxy and it emitted out following message "Got a continuation header but had no previous header line". Looked it up online and found that the problem was in multi-line requestline. I was setting the HTTP version to 1.1 explicitly however there was a trailing '\r\n' in the url which made the requestline look like Http/0.9.
Difference between Http/0.9 and Http/1.0 or other higher protocols is that 0.9 had a simple requestline 'METHOD URL'. Later versions also include the Http version in the request line 'METHOD URL HTTPVERSION'.
Hope it saves someone day!