Trying to stream video to windows media player from a servlet (progressive download style). The streaming works, but I have some weird behavior, which I would like to rule out is not caused by a problem in my implementation.
When using WMP to open an url from the servlet, WMP will perform a total of 4 http-get requests for the same resource, but with slightly different headers each time. The connection for the first 3 requests seems to be closed as soon as the request (including headers) have been sent. The fourth request remains connected, and I can actually deliver response headers and the file content.
Have tried using wireshark to watch the first three requests. Identical starts of responses are sent for all 4 requests, and the first 3 requests managed to send the response headers, and some part of the file content before being closed. (Don't know if its relevant, but have to enable "Support packet-capture from IP TSO-enabled hardware" for wireshark to correctly parse the stream, otherwise the first packet containing the http-response is seen as malformed.)
The 4 request headers below here:
GET /basic/test.mpg HTTP/1.1
Accept: */*
User-Agent: Windows-Media-Player/12.0.7600.16415
Accept-Encoding: gzip, deflate
Host: 192.168.1.34
Connection: Keep-Alive
GET /basic/test.mpg HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: getIfoFileURI.dlna.org
Accept: */*
User-Agent: NSPlayer/12.00.7600.16385 WMFSDK/12.00.7600.16385
GetContentFeatures.DLNA.ORG: 1
Host: 192.168.1.34
GET /basic/test.mpg HTTP/1.1
Accept: */*
User-Agent: NSPlayer/12.00.7600.16385 WMFSDK/12.00.7600.16385
Icy-Metadata: 1
Accept-Encoding: gzip, deflate
Host: 192.168.1.34
Connection: Keep-Alive
GET /basic/test.mpg HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: getIfoFileURI.dlna.org
Accept: */*
User-Agent: NSPlayer/12.00.7600.16385 WMFSDK/12.00.7600.16385
GetContentFeatures.DLNA.ORG: 1
Host: 192.168.1.34
Response headers:
HTTP/1.1 200 OK
Content-Type: video/mpeg
Content-Length: 130549760
ETag: TEST1286565215430
ContentFeatures.DLNA.ORG: DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=00
Server: Jetty(6.1.x)
The connection for the first 3 requests seems to be closed as soon as the request (including headers) have been sent.
"Seems to be"? I would find out for certain one way or the before proceeding. If it is ending the connection after the response headers are set, it could be that the player was expecting a very specific header to be present. Examples could include Range: or Cache-Control:.
Related
I am sending a simple POST request with the built-in HttpURLConnection class, but I want to change the way Java separates the headers from the body (look at the outputs of tcpflow -a port 80 below). Here is the code:
// Create HttpURLConnection object
URL url = new URL("http://httpbin.org/post");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Set request method
connection.setRequestMethod("POST");
// Write body and "Content-Length" header
String body = "This+is+the+body+of+the+post+request.";
connection.setRequestProperty("Content-Length",
String.valueOf(body.length()));
connection.setDoOutput(true);
connection.getOutputStream().write(body.getBytes("US-ASCII"));
// Send request
int responseCode = connection.getResponseCode();
When I execute that code and look at what Java actually sends using tcpflow -a port 80 (prints all requests/responses on port 80), I see the following (I cut away the response):
192.168.178.113.54654-054.225.177.165.00080: POST /post HTTP/1.1
User-Agent: Java/9
Host: httpbin.org
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-type: application/x-www-form-urlencoded
Content-Length: 37
192.168.178.113.54654-054.225.177.165.00080: This is the body of the post request.
The headers are correct, the body is correct. But I can see that the body is transferred in a separate connection. I know that this is a problem with java.net.HttpURLConnection because when I try the same with Apache's HttpClient, tcpflow -a port 80 gives me:
192.168.178.113.39708-054.243.202.193.00080: POST /post HTTP/1.1
Content-Length: 37
Host: httpbin.org
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.3 (Java/9)
Accept-Encoding: gzip,deflate
This+is+the+body+of+the+post+request.
Here the body is sent with the headers, separated with just /r/n/r/n. I would like the Java library (java.net.HttpURLConnection) to do the same. Is that possible?
EDIT: I found out that the reason the server rejected my requests was not that the body was in a different packet (packet, not connection, as Julian Reschke pointed out) than the headers but just that I sent the wrong data facepalm.
I have read this: compress-responses-in-jersey and have Jersey 2 config:
#ApplicationPath("/jaxrs/")
public class AppConfig extends ResourceConfig {
public AppConfig() {
super(AdvertisementResource.class, MultiPartFeature.class);
packages("jaxrs");
EncodingFilter.enableFor(this, GZipEncoder.class, DeflateEncoder.class);
}
}
I have header Request:
GET http://localhost:8081/jaxrs/admin-adblock
Accept:application/json
Cache-Control:no-cache
Content-Type:application/json
Authorization:Basic c21h...
Accept-Encoding:gzip,deflate
But header response are:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept-Encoding
Server: Jetty(9.2.2.v20140723)
Header in response Content-Encoding:gzip is missing only Vary: Accept-Encoding is appear if I have:
EncodingFilter.enableFor(this, GZipEncoder.class, DeflateEncoder.class);
If I remove compression and comment EncodingFilter row response header are:
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Server: Jetty(9.2.2.v20140723)
or this:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 369
Server: Jetty(9.2.2.v20140723)
I`m testing with Intellij Rest Client Tool and I`m not sure if I receive compressed response from server?
I have download jersey sources and set breakpoint here and debug rest service web application with Intellij it appears that CONTENT_ENCODING gzip is added here:
response.getHeaders().putSingle(HttpHeaders.CONTENT_ENCODING, contentEncoding);
but its missing in response header from Intellij Rest Client tool..
I have download SoapUI and test the same Rest requests response headers:
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 204
Server: Jetty(9.2.2.v20140723)
The Intellij Rest Client Tool is hiding response headers Content-Encoding and Content-Length..
I have open new issue
I am able to set content type using cxf library but I don't know how to set Authorization header. Whenever I set user name and password then it set Authorization header and encode whole value and add Basic. I don't want to do this. I want to add Authorization header with plain string which ever I provide. Please help me to solve out this problem.
AMPServices services = new AMPServices();
CoreXmlPort coreXmlPort = services.getAMPSoapService();
Client client = ClientProxy.getClient(coreXmlPort);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy=httpConduit.getClient();
String contentType=httpClientPolicy.getContentType();
contentType="application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8";
httpClientPolicy.setContentType(contentType);
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("username");
authorizationPolicy.setPassword("password");
httpConduit.setAuthorization(authorizationPolicy);
It generates following request xml.
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: Basic aXNoaXAgcGIvd3NkZXZlbDowNzZhNjFjYTM5MDcxODAxODVjNWRkMjM2YTdkMzZhNGQ1ODg5OWFj
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I want this type of request
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: username;password
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I was not able to do it. Please help me to solve out this problem.
Thanks,
Awadhendra
I think you are trying to call is a RestFul Service, so that's why the server side always response with a different content type than you expected (json instead of soap/xml). Is your url endpoint based on http protocol? If yes, do you need send additional parameters to this url?
The issue here is that the client you are using to interact with Webservice expecting XML based Soap Messages , while the service is serving JSON as a return media.
Either convert your client to use the JSON format and communicate using that, or alternatively use the XML based endpoint , consult with webservice provider for that.
I've written a server socket code that receives http request and print it on console.
Given below is the server code.
clientSocket = echoServer.accept();
is = new DataInputStream(clientSocket.getInputStream());
while (true)
{
line = is.readLine();
System.out.println(line);
}
The output is:
POST / HTTP/1.1
User-Agent: Java/1.6.0_20
Host: 127.0.0.1:4000
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-type: application/x-www-form-urlencoded
Content-Length: 7
Hello
I don't want header in my output, How can I get only Body part in my output that is "Hello"?
HTTP requests starts with a status line followed by header lines followed by the body. the request/header lines are separated by a single CRLF (\r\n), but the body is separated from them with additional CRLF:
POST / HTTP/1.1
User-Agent: Java/1.6.0_20
Host: 127.0.0.1:4000
Accept: text/html, image/gif, image/jpeg, *; q=.2, /; q=.2
Connection: keep-alive
Content-type: application/x-www-form-urlencoded
Content-Length: 7
Hello
E.g. you need to look for the first empty line. after than the body starts.
When I set "Authorization" header with setHeader from HttpPost then hostname disappears from request and there is always error 400 (bad request) returned. Same code is working fine on pure java (without android) and when I remove setting "Authorization" header also on android it works fine, but I need authorization.
This is a code (domain changed):
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://myhost.com/test.php");
post.setHeader("Accept", "application/json");
post.setHeader("User-Agent", "Apache-HttpClient/4.1 (java 1.5)");
post.setHeader("Host", "myhost.com");
post.setHeader("Authorization",getB64Auth());
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("data[body]", "test"));
AbstractHttpEntity ent=new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
ent.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
ent.setContentEncoding("UTF-8");
post.setEntity(ent);
post.setURI(new URI("http://myhost.com/test.php"));
HttpResponse response =client.execute(post);
Method getB64Auth() returns "login:password" encoded using Base64 like: "YnxpcYRlc3RwMTulHGhlSGs=" but it's not important.
This is a piece of lighttpd's error.log when above code is invoked on pure java:
2011-02-23 15:37:36: (request.c.304) fd: 8 request-len: 308
POST /test.php HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: myhost.com
Authorization: Basic YnxpcYRlc3RwMTulHGhlSGs=
Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Encoding: UTF-8
Connection: Keep-Alive
HTTP/1.1 200 OK
Content-type: text/html
Transfer-Encoding: chunked
and record from access.log (IP changed):
1.1.1.1 myhost.com - [23/Feb/2011:15:37:36 +0100] "POST /test.php HTTP/1.1" 200 32 "-" "Apache-HttpClient/4.1 (java 1.5)"
When the same code is invoked on android, I get this in logs:
POST /test.php HTTP/1.1
Accept: application/json
User-Agent: Apache-HttpClient/4.1 (java 1.5)
Host: myhost.com
Authorization: Basic YnxpcYRlc3RwMTulHGhlSGs=
Content-Length: 21
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Encoding: UTF-8
Connection: Keep-Alive
Expect: 100-Continue
2011-02-23 15:45:10: (response.c.128) Response-Header:
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close
access.log:
1.1.1.1 - - [23/Feb/2011:15:45:10 +0100] "POST /test.php HTTP/1.1" 400 349 "-" "Apache-HttpClient/4.1 (java 1.5)"
How to get Authorization with POST working on android?
When I use HttpURLConnection instead of HttpClient it is no difference.
Thanks to Samuh for a hint :)
There was an extra newline character inserted which has no means in GET requests, but matters in POST ones.
This is proper way to generate Authorization header in android (in getB64Auth in this case):
private String getB64Auth (String login, String pass) {
String source=login+":"+pass;
String ret="Basic "+Base64.encodeToString(source.getBytes(),Base64.URL_SAFE|Base64.NO_WRAP);
return ret;
}
The Base64.NO_WRAP flag was lacking.
use simply this :
String authorizationString = "Basic " + Base64.encodeToString(
("your_login" + ":" + "your_password").getBytes(),
Base64.NO_WRAP); //Base64.NO_WRAP flag
post.setHeader("Authorization", authorizationString);