grpc metadata not showing in http header - c++

I am trying to send a grpc request from a c++ client to a server. On the way the http passes through a proxy that checks http header fields. I wanted to add a custom field version to be checked by that proxy.
I am adding it to the grpc context and sending the request:
protos::MyProtoRequest req;
protos::MyProtoResponse res;
grpc::ClientContext context;
context.AddMetadata("version", "0.1.2");
// proto_stub is a protobuf stub interface
const grpc::Status status = proto_stub->MyOperation(&context, req, &res);
Then inside my proxy I inspect the http header and I do not see a version field in it.
I once did something similar but with the name authorization instead of version and it worked. Here I am doing the same thing with another name and it fails. I am confused. What am I doing wrong?
Thank you

Related

Apollo Client sending requests to wrong uri

I'm using Apollo Client to send requests to a graphql server. I created a link with apollo-upload-client since I need it for what I'm doing. The client is defined as follows:
const link = createUploadLink({
uri: 'http://localhost:4000/graphql'
});
const client = new ApolloClient({link});
However, when I try to make a mutation, it sends the request to http://localhost:3000/graphql instead. This results in a failed request, as that is not where the server is. Strangely, requests work fine if I specify the uri directly in the client like this:
client = new ApolloClient({uri: 'http://localhost:4000/graphql});
At first I thought it might be a problem with createUploadLink, but even using HttpLink causes this problem.
Why does the client request the wrong address when using links?
It turns out the problem was where I was importing ApolloClient from. I was originally importing it from apollo-boost. It worked when I imported it from #apoloo/client.

How to disable chunking in cxf webservice on server-side?

I need to disable chunking in cxf webservice on server-side as some clients need 'Content-Length' header in response. Now i can see 'Transfer-Encoding' is 'chunked' in server response and no 'Content-Length' header is sent.
I've found that chunkins can be disabled in spring's context like this:
<http-conf:conduit name="*.http-conduit">
<http-conf:client ReceiveTimeout=“300000“ AllowChunking="false"/>
</http-conf:conduit>
Since i'm creating services programmatically like this:
// media service
Object mediaService = new MediaService();
System.out.println("Starting media service #1 ...");
EndpointImpl mediaEP = (EndpointImpl)Endpoint.create(mediaService);
mediaEP.publish("http://localhost:8081/onvif/media_service");
How can i do it?
Actually, you can't easyly specified to not allow chuncking from server side.
Indeed, it's a client pb! What I understand is that you have a client of your ws who can't modify his code to desactivate chunking?
You have to do that : write a CXF interceptor that would replace the servlets OutputStream in the message with a buffer of some sort (ByteArrayOutputStream or CachedOutputStream) at the beginning of the output chain and then at the end of the chain, use that to set the Content-Length header on the response and copy that data to the real output stream.
Indeed, the content lenght will force the framework to not use the chunking.
I did it once before. I'll try to post you maybe tomorrow a code of such interceptor.

HTTP error code: 302 when calling https webservice

I am trying to call a SOAP RPC style web service and getting the following error:
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 302:
This is a https web service and I have imported the certificate into cacerts thru browser but getting same result. Please note that, I can consume a REST webservice from the same machine without importing the certificate.
What I am missing when calling a SOAP service? Is it my client issue or something need to be done on the server side. I have access to the server.
HTTP status code 302 is a redirect, and so is unlikely due to a certificate problem. My initial guess is that you need to add a / (or remove it) from your URL. Some http server frameworks will redirect when a resource does not end in a /, so, instead of:
GET /myRpcEndpoint
Try
GET /myRpcEndpoint/
The other possibility is that this resource requires authentication and the server is redirecting you to a login page. If you want to know what is going on (and not guess), take a look a the the response headers for the 302. There will be a Location header telling you where the server wants you to go instead.
Had a similar issue where client code would receive a HTTP 302 error code when communicating with https and would work fine when communicating with http. In client code,you might need to specify the endpoint address on the request context using the BindingProvider.ENDPOINT_ADDRESS_PROPERTY property. Following the JAX-WS paradigm, the example below should work.
Please note that only the BindingProvider.ENDPOINT_ADDRESS_PROPERTY needs to be defined, the rest of your code should remain the same.
public static void main(String args[]) throws {
ObjectFactory factory = new ObjectFactory();
GetProducts_Service service = new GetProducts_Service();
GetProducts getProducts = service.getGetProductsPort();
final BindingProvider getProductsBP = (BindingProvider) getProducts;
getProductsBP.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"https://example.server.net/ExampleServicesWar/GetProducts");
GetProductsRequest request = factory.createGetProductsRequest();
GetProductsResponse response=getProducts.getProducts(request);
List<Product> products=response.getProducts();
}
All you have to is to use correct end point url
((BindingProvider)port).getRequestContext().put(BindingProvider.
ENDPOINT_ADDRESS_PROPERTY, "https://yourservice");
Need to import at the top:
import javax.xml.ws.BindingProvider;
port is Method call:
full source:
private static String getApplicationStatus(java.lang.String remoteAccessKey, java.lang.Integer responseId) {
net.quotit.oes._2010.ws.applicationstatusupdate.OASStatusUpdateService service = new net.quotit.oes._2010.ws.applicationstatusupdate.OASStatusUpdateService();
net.quotit.oes._2010.ws.applicationstatusupdate.IApplicationStatusUpdate port = service.getStatusUpdate();
((BindingProvider)port).getRequestContext().put(BindingProvider.
ENDPOINT_ADDRESS_PROPERTY, "https://servicename/basic");
return port.getApplicationStatus(remoteAccessKey, responseId);
}

Stub generated using Axis2 Webservice forming new connection for redirect URL...Need same TCP connection...!

I am badly stuck with a SOAP based integration using Axis2 framework for generation of client stubs from the Server WSDL. The scenario is as follows :
There is always a login API call first, which gives a Success response in SOAP body and Temporary Redirect in HTTP header. Also provides a URL which contains the session ID in the Location field of HTTP Header.
The next API call is required to be made at this redirect location. IN THE SAME TCP CONNECTION, for getting a proper response.
Now, the problem is, as a part of Webservice implementation using Axis2 generated stubs, I need to reload this redirect URL and re-instantiate it as --- "stub=new Stub(newurl)"
As soon as this is done, it creates a new TCP connection and so, the next request gives the response as "session ID invalid" because it goes out-of-sync with login API.
I have tried everything mentioned as a solution in this forum and nothing is working out.
For e.g --
MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
HttpClient httpClient = new HttpClient(httpConnectionManager);
ServiceClient serviceClient = stub._getServiceClient();
Options opts = stub._getServiceClient().getOptions();
opts.setTo(new EndpointReference(prop.getProperty("target_end_point_url")));
opts.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Constants.VALUE_TRUE);
opts.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
serviceClient.setOptions(opts);
stub._setServiceClient(serviceClient);
Similarly, I have tried many other options too. But it's not helpful at all.
Faced exactly the same issue.
Following steps solved the issue.
1. Using HttpClient, perform login. Don't use stub object to perform login.
2. Use the Location Header URL, to create new stub object i.e. stub = new Stub(locationURL). (Your existing options setting should be retained.)
3. There is a default timeout, by which server disconnects the TCP connection. In my case it was 50 seconds. Hence as soon as i performed login in step 1, i execute a timer every 40 seconds, to send an empty requests to new Location URL using HeadMethod of same HttpClient object.

Setting HTTP headers through Axis2 API

I am using apache axis2 server webservies, Basically I am sending xml response to android client through webservices. Here I need to maintain the session since the services per user basis. I know maintaining session in webservices is bad idea, but cant avoid it.
Actually I need to generate random unique string when user invoke first service from android client, that random string going to be used as session id. This session id, i need to set in http custom header, so that android client can able to get it and can send it subsequent requests as well.
I want to know whether any API is available in axis2 to set custom header information on http headers. Same way I need to read the http header, so that next request I can get the session id from header.
Can anyone advice me regarding this?? Thanks
-Ravi
Dead link on #Martin Dürrmeier's answer, here's a snapshot of the webpage that i've found on web.archive.org : Axis2 - Setting custom HTTP Headers on a response, it helped me.
Here's the lines needed :
MessageContext responseMessageContext =
MessageContext.getCurrentMessageContext().getOperationContext().getMessageContext(
WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
List<Header> headers = new ArrayList<Header>();
headers.add(new Header(HTTPConstants.HEADER_CONTENT_ENCODING, "identity"));
responseMessageContext.setProperty(HTTPConstants.HTTP_HEADERS, headers);