for reason there no 'content-length' http headers in cxf response. i've decided implement interceptor it, unfortunately there no added header in sent data (intercepted using wireshark). can set breakpoint , can see interceptor invoked. what's wrong?
/** * adds content-length header outcoming messages */ public class addcontentlengthinterceptor extends abstractlogginginterceptor { private static final string content_length_added = addcontentlengthinterceptor.class.getname() + ".log-setup"; public addcontentlengthinterceptor(string phase) { super(phase); addbefore(staxoutinterceptor.class.getname()); } public addcontentlengthinterceptor() { this(phase.pre_protocol); // before streaming } @override protected logger getlogger() { return null; } @override public void handlemessage(message message) throws fault { final outputstream os = message.getcontent(outputstream.class); final writer iowriter = message.getcontent(writer.class); if (os == null && iowriter == null) { return; } // ignore double processing of message boolean hasaddedheader = message.containskey(content_length_added); if (!hasaddedheader) { message.put(content_length_added, boolean.true); if (os != null) { // write output while caching adding header later final cacheandwriteoutputstream newout = new cacheandwriteoutputstream(os); message.setcontent(outputstream.class, newout); newout.registercallback(new loggingcallback(message, os)); } } } class loggingcallback implements cachedoutputstreamcallback { private final message message; private final outputstream origstream; public loggingcallback(final message msg, final outputstream os) { this.message = msg; this.origstream = os; } public void onflush(cachedoutputstream cos) { } public void onclose(cachedoutputstream cos) { long contentlength = cos.size(); map<string, list<string>> headers = (map<string, list<string>>) message.get(message.protocol_headers); if (headers == null) headers = new hashmap<string, list<string>>(); headers.put("content-length", arrays.aslist(string.valueof(contentlength))); message.put(message.protocol_headers, headers); try { // empty out cache cos.lockoutputstream(); cos.resetout(null, false); } catch (exception ex) { //ignore } message.setcontent(outputstream.class, origstream); } } } this server-side endpoints created:
mediaservice = new mediaservice(ip, rtspport, streamuri); providerimpl provider = new providerimpl(); mediaendpoint = (endpointimpl) provider.createendpoint(null, mediaservice); string mediaserviceurl = messageformat.format("http://{0}:{1}/onvif/media_service", ip, string.valueof(port)); mediaendpoint.publish(mediaserviceurl); // add "content-length" header mediaendpoint.getserver().getendpoint().getoutinterceptors().add(contentlengthinterceptor);
i think using transfer-encoding chunked. results in no content-length header since defined way in rfc.
messages must not include both content-length header field , non-identity transfer-coding. if message include non-identity transfer-coding, content-length must ignored.
i not sure but, either cxf removes header since not allowed or sets sub layers remove it. far know cxf uses httpurlconnection transport message. , layer sets content-length header on normal cases. since using chunked transfer, layer may override it.
in order fix must change transfer-encoding. , since cxf's sets content-length header no longer need write interceptor.
by way, if use custom header, realise interceptor works charm.
Comments
Post a Comment