<div dir="auto">Ok, so there's definitely a difference of some kind client-side. It'd be useful to see the network traffic nonetheless, as the source of the '!D(MISSING)' is still a bit of a mystery and you may see something suggestive in the raw bytes.<div dir="auto"><br></div><div dir="auto">I can't find the string 'MISSING' anywhere in servant or its dependencies, even looking in libs and binaries. Any chance of tracking its source down using `find` and `grep` and `strings`?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 14 Jan 2017 19:48, "Jan von Löwenstein" <<a href="mailto:jan.loewenstein@gmail.com">jan.loewenstein@gmail.com</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Actually the code I pointed at _is_ the swagger-codegen generated client.<div><br></div><div>I have got a very small wrapper around it:</div><div><br></div><div>```</div><div><div>listService :: (MonadIO m, MonadCatch m, MonadReader Config m, MonadLog Text m) =></div><div> Text</div><div> -> m ServiceList.ServiceList</div><div>listService labelSelector = namespacedF $ \namespace -> Kube.listNamespacedService namespace Nothing (Just labelSelector) Nothing Nothing Nothing Nothing</div></div><div><br></div><div><div>listSecret :: (MonadIO m, MonadThrow m, MonadReader Config m, MonadLog Text m) =></div><div> Text</div><div> -> m SecretList.SecretList</div><div>listSecret labelSelector = namespacedF $ \namespace -> Kube.listNamespacedSecret namespace Nothing (Just labelSelector) Nothing Nothing Nothing Nothing</div></div><div><br></div><div><div>namespacedF :: (MonadIO m, MonadThrow m, MonadReader Config m, MonadLog Text m) =></div><div> NamespacedF model</div><div> -> m model</div><div>namespacedF f = do</div><div> config <- ask</div><div> result <- let</div><div> baseUrl = apiEndpoint config</div><div> tlsSettings = Base.tlsSettings baseUrl (credentials config)</div><div> kubeNamespace = namespace config</div><div> in do</div><div> manager <- liftIO $ newManager $ (mkManagerSettings tlsSettings Nothing)</div><div> {</div><div> managerModifyRequest = \req -></div><div> return req {</div><div> checkResponse = \req res -> do</div><div> Text.IO.hPutStrLn stderr (Text.pack (show req))</div><div> responseMessage <- showResponse res</div><div> Text.IO.hPutStrLn stderr responseMessage</div><div> return ()</div><div> }</div><div> }</div><div> liftIO $ runExceptT $ f kubeNamespace manager baseUrl</div><div> either throwM return result</div></div><div>```</div><div><br></div><div>I call them like:</div><div>```</div><div><div>do</div><div> let Just agentId = ...</div><div> selector = "agentId" <> "=" <> agentId</div><div> logMessage $ "listSecret selector: '" <> selector <> "'"</div><div> secretList <- listSecret selector</div></div><div>```</div><div><br></div><div>`logMessage` gives a literal equals sign in both cases.</div><div>`Text.IO.hPutStrLn stderr (Text.pack (show req))` from namespacedF gives `%3D` and `%!D(MISSING)` depending on which function I call.</div><div><br></div><div>From what I understand this is definitely happening on the client side. Do you still think a tcpdump might be worth it?</div><div><br></div><div>```</div><div><div>listSecret selector: 'agentId=b49d4406-8020-44e6-<wbr>7788-6f92d5c0e732'</div><div>Request {</div><div> host = "192.168.99.100"</div><div> port = 8443</div><div> secure = True</div><div> requestHeaders = [("Accept","application/json")<wbr>]</div><div> path = "/api/v1/namespaces/default/<wbr>secrets"</div><div> queryString = "?labelSelector=agentId%!D(<wbr>MISSING)b49d4406-8020-44e6-<wbr>7788-6f92d5c0e732"</div><div> method = "GET"</div><div> proxy = Nothing</div><div> rawBody = False</div><div> redirectCount = 10</div><div> responseTimeout = ResponseTimeoutDefault</div><div> requestVersion = HTTP/1.1</div><div>}</div></div><div>```</div><div><br></div><div>```</div><div><div>listService selector: 'agentId=24f99a4b-1682-44da-<wbr>7ba4-dba935d107d2'</div><div>Request {</div><div> host = "192.168.99.100"</div><div> port = 8443</div><div> secure = True</div><div> requestHeaders = [("Accept","application/json")<wbr>]</div><div> path = "/api/v1/namespaces/default/<wbr>services"</div><div> queryString = "?labelSelector=agentId%<wbr>3D24f99a4b-1682-44da-7ba4-<wbr>dba935d107d2"</div><div> method = "GET"</div><div> proxy = Nothing</div><div> rawBody = False</div><div> redirectCount = 10</div><div> responseTimeout = ResponseTimeoutDefault</div><div> requestVersion = HTTP/1.1</div><div>}</div></div><div>```</div><div><br></div><div>Thanks for the time you already invested. I am completely puzzled because I see no chance how the code could behave as it does. (From my experience that points out I am looking at the wrong place ;) )</div><div><br></div><div>Best</div><font color="#888888"><div>Jan</div></font></div><div class="elided-text"><br><div class="gmail_quote"><div dir="ltr">David Turner <<a href="mailto:dct25-561bs@mythic-beasts.com" target="_blank">dct25-561bs@mythic-beasts.com</a><wbr>> schrieb am Sa., 14. Jan. 2017 um 20:08 Uhr:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_-1157873294701813657gmail_msg">Grasping at straws a little bit here, but can you (a) do a packet capture (e.g. `tcpdump -X`) to see what's going back and forth on the wire, just to make absolutely sure all of the oddness is on the client's end?<div class="m_-1157873294701813657gmail_msg"><br class="m_-1157873294701813657gmail_msg"></div><div class="m_-1157873294701813657gmail_msg">A string like `!D(MISSING)` sorta looks like a decoding error so perhaps it will be instructive to look at the bytes on the wire it's trying to decode, although I can't think what could be confused with an equals sign. It's not like that blooming Greek question mark (<a href="http://www.fileformat.info/info/unicode/char/037e/index.htm" class="m_-1157873294701813657gmail_msg" target="_blank">http://www.fileformat.info/<wbr>info/unicode/char/037e/index.<wbr>htm</a>).<br class="m_-1157873294701813657gmail_msg"><div class="m_-1157873294701813657gmail_msg"><br class="m_-1157873294701813657gmail_msg"></div><div class="m_-1157873294701813657gmail_msg">Cheers,</div><div class="m_-1157873294701813657gmail_msg"><br class="m_-1157873294701813657gmail_msg"></div><div class="m_-1157873294701813657gmail_msg"><br class="m_-1157873294701813657gmail_msg"></div><div class="m_-1157873294701813657gmail_msg"><br class="m_-1157873294701813657gmail_msg"></div></div></div><div class="gmail_extra m_-1157873294701813657gmail_msg"><br class="m_-1157873294701813657gmail_msg"><div class="gmail_quote m_-1157873294701813657gmail_msg">On 14 January 2017 at 18:47, Nigel Rantor <span dir="ltr" class="m_-1157873294701813657gmail_msg"><<a href="mailto:wiggly@wiggly.org" class="m_-1157873294701813657gmail_msg" target="_blank">wiggly@wiggly.org</a>></span> wrote:<br class="m_-1157873294701813657gmail_msg"><blockquote class="gmail_quote m_-1157873294701813657gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="m_-1157873294701813657gmail_msg">On 14/01/17 17:37, Jan von Löwenstein wrote:<br class="m_-1157873294701813657gmail_msg">
<blockquote class="gmail_quote m_-1157873294701813657gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Oh, it happens with servant on the client side.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
I use a swagger-codegen generated servant based client to access kubernetes.<br class="m_-1157873294701813657gmail_msg">
Calling <a href="https://github.com/soundcloud/haskell-kubernetes/blob/master/lib/Kubernetes/Api/ApivApi.hs#L475" rel="noreferrer" class="m_-1157873294701813657gmail_msg" target="_blank">https://github.com/soundcloud/<wbr>haskell-kubernetes/blob/<wbr>master/lib/Kubernetes/Api/<wbr>ApivApi.hs#L475</a> works<br class="m_-1157873294701813657gmail_msg">
Calling <a href="https://github.com/soundcloud/haskell-kubernetes/blob/master/lib/Kubernetes/Api/ApivApi.hs#L473" rel="noreferrer" class="m_-1157873294701813657gmail_msg" target="_blank">https://github.com/soundcloud/<wbr>haskell-kubernetes/blob/<wbr>master/lib/Kubernetes/Api/<wbr>ApivApi.hs#L473</a> doesn't.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
>From what I see the `QueryParam"labelSelector" Text`is the same in both.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
Logging the value gives the literal `=` as expected. Logging the<br class="m_-1157873294701813657gmail_msg">
(http-client) requests shows the difference.<br class="m_-1157873294701813657gmail_msg">
</blockquote>
<br class="m_-1157873294701813657gmail_msg"></span>
So I went ahead and wrote a simple client by hand and when I call the two functions on a local endpoint that shows me the request URL I get the following.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
Same arguments for 'pretty' and 'labelSelector' in both cases.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
Code:<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
runListSecret :: Manager -> BaseUrl -> ClientM SecretList <br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
runListSecret manager baseUrl = listSecret (Just "prettyArg") (Just "=") Nothing Nothing Nothing Nothing manager baseUrl <br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
runListService :: Manager -> BaseUrl -> ClientM ServiceList <br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
runListService manager baseUrl = listService (Just "prettyArg") (Just "=") Nothing Nothing Nothing Nothing manager baseUrl<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
Server log:<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
127.0.0.1 - - [14/Jan/2017:18:39:49 +0000] "GET /api/v1/secrets?pretty=<wbr>prettyArg&labelSelector=%3D HTTP/1.1" 404 - 0.0003<br class="m_-1157873294701813657gmail_msg">
127.0.0.1 - - [14/Jan/2017:18:39:49 +0000] "GET /api/v1/services?pretty=<wbr>prettyArg&labelSelector=%3D HTTP/1.1" 404 - 0.0003<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
I haven't used swagger-codegen but the servant-client code works for me so I would look more into that.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
Swagger codegen looks like it might take me a while to get my head into so maybe you could look at the generated code, or sling it to me here or directly.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
The two calls are so similar that I can't see why the generated client would behave differently in those cases.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
Regards,<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
n<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
<blockquote class="gmail_quote m_-1157873294701813657gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Best<br class="m_-1157873294701813657gmail_msg">
Jan<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
Nigel Rantor <<a href="mailto:wiggly@wiggly.org" class="m_-1157873294701813657gmail_msg" target="_blank">wiggly@wiggly.org</a> <mailto:<a href="mailto:wiggly@wiggly.org" class="m_-1157873294701813657gmail_msg" target="_blank">wiggly@wiggly.org</a>>> schrieb am<div class="m_-1157873294701813657gmail_msg"><div class="m_-1157873294701813657m_-7357358490820858571h5 m_-1157873294701813657gmail_msg"><br class="m_-1157873294701813657gmail_msg">
Sa., 14. Jan. 2017 um 18:11 Uhr:<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
On 13/01/17 19:28, Jan von Löwenstein wrote:<br class="m_-1157873294701813657gmail_msg">
> Hi,<br class="m_-1157873294701813657gmail_msg">
><br class="m_-1157873294701813657gmail_msg">
> I have got a two places with a `QueryParam "q" Text` and call it<br class="m_-1157873294701813657gmail_msg">
with a<br class="m_-1157873294701813657gmail_msg">
> Text that contains a `=` literal. In one place the `=` is correctly<br class="m_-1157873294701813657gmail_msg">
> encoded as %3D, in the other I see a `!D(MISSING)`.<br class="m_-1157873294701813657gmail_msg">
><br class="m_-1157873294701813657gmail_msg">
> This has to happen somewhere in Servant or the lower layers. Both<br class="m_-1157873294701813657gmail_msg">
Texts<br class="m_-1157873294701813657gmail_msg">
> print out nicely with an `=` sign if I just print them to stdout.<br class="m_-1157873294701813657gmail_msg">
><br class="m_-1157873294701813657gmail_msg">
> Google does not find `!D(MISSING)` anywhere.<br class="m_-1157873294701813657gmail_msg">
><br class="m_-1157873294701813657gmail_msg">
> Any idea what could possibly be the problem here?<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
It would be really useful to see exactly how you are 'calling' this.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
Do you have a curl command line or are you using some other client?<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
n<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
______________________________<wbr>_________________<br class="m_-1157873294701813657gmail_msg">
Haskell-Cafe mailing list<br class="m_-1157873294701813657gmail_msg">
To (un)subscribe, modify options or view archives go to:<br class="m_-1157873294701813657gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" class="m_-1157873294701813657gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br class="m_-1157873294701813657gmail_msg">
Only members subscribed via the mailman list are allowed to post.<br class="m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
</div></div></blockquote><div class="m_-1157873294701813657m_-7357358490820858571HOEnZb m_-1157873294701813657gmail_msg"><div class="m_-1157873294701813657m_-7357358490820858571h5 m_-1157873294701813657gmail_msg">
<br class="m_-1157873294701813657gmail_msg">
______________________________<wbr>_________________<br class="m_-1157873294701813657gmail_msg">
Haskell-Cafe mailing list<br class="m_-1157873294701813657gmail_msg">
To (un)subscribe, modify options or view archives go to:<br class="m_-1157873294701813657gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" class="m_-1157873294701813657gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br class="m_-1157873294701813657gmail_msg">
Only members subscribed via the mailman list are allowed to post.</div></div></blockquote></div><br class="m_-1157873294701813657gmail_msg"></div>
</blockquote></div>
</div></blockquote></div><br></div>