Skip to content

Basic Auth Failure Manifests as "Invalid JSON string" #1901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
seanwm opened this issue Mar 10, 2016 · 1 comment · Fixed by #1913
Closed

Basic Auth Failure Manifests as "Invalid JSON string" #1901

seanwm opened this issue Mar 10, 2016 · 1 comment · Fixed by #1913
Assignees

Comments

@seanwm
Copy link

seanwm commented Mar 10, 2016

When using Basic Authentication (via BasicAuthentication(username, password) on the ConnectionConfiguration object), an authentication failure causes an "Invalid JSON string" exception to be thrown. It'd be helpful for an auth failure to throw a more appropriate error message.

The JSON error is understandable, because Nginx (which we're using as a reverse proxy for auth) returns a block of HTML with 401's by default:

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.4.6 (Ubuntu)</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->

Nevertheless, I think it'd be worthwhile for Elasticsearch.Net to check the response code and skip deserializing the body for 401's.

Speaking of deserialization, I ran into this calling the GetSourceAsync method (with a custom C# object as T). But even if I asked for VoidResponse, Stream, or byte[] as the type, I was still getting the JSON parsing error. While the docs state that there's no deserialization when those are the response types, the fact that I continued to see the deserialization error suggests that (at least when using GetSourceAsync) the content is deserialized regardless of the return type. The entire (lightly-edited) Debug Information for the exception is below.

And yes, really, this is all my fault for being a dope about loading the username/password from a config file :) But maybe a small change would help the next dope. Thanks for your time!

# FailureReason: Unexpected when trying to GET https://example.com/contacts/contact/myContactID/_source?routing=MyContactRouting
 - BadResponse: Node: https://example.com/ Exception: SerializationException Took: 00:00:00.4114099
# Audit exception in step 0 BadResponse:
System.Runtime.Serialization.SerializationException: Invalid JSON string
   at Elasticsearch.Net.SimpleJson.DeserializeObject(String json)
   at Elasticsearch.Net.SimpleJson.DeserializeObject(String json, Type type, IJsonSerializerStrategy jsonSerializerStrategy)
   at Elasticsearch.Net.SimpleJson.DeserializeObject[T](String json, IJsonSerializerStrategy jsonSerializerStrategy)
   at Elasticsearch.Net.ElasticsearchDefaultSerializer.<DeserializeAsync>d__3`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.ResponseBuilder`1.<SetBodyAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.ResponseBuilder`1.<ToResponseAsync>d__16.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.HttpConnection.<RequestAsync>d__7`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.RequestPipeline.<CallElasticsearchAsync>d__66`1.MoveNext()
   at Elasticsearch.Net.ExceptionExtensions.RethrowKeepingStackTrace(Exception exception)
   at Elasticsearch.Net.RequestPipeline.<CallElasticsearchAsync>d__66`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.Transport`1.<RequestAsync>d__15`1.MoveNext()
# Inner Exception: Invalid JSON string
System.Runtime.Serialization.SerializationException: Invalid JSON string
   at Elasticsearch.Net.SimpleJson.DeserializeObject(String json)
   at Elasticsearch.Net.SimpleJson.DeserializeObject(String json, Type type, IJsonSerializerStrategy jsonSerializerStrategy)
   at Elasticsearch.Net.SimpleJson.DeserializeObject[T](String json, IJsonSerializerStrategy jsonSerializerStrategy)
   at Elasticsearch.Net.ElasticsearchDefaultSerializer.<DeserializeAsync>d__3`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.ResponseBuilder`1.<SetBodyAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.ResponseBuilder`1.<ToResponseAsync>d__16.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.HttpConnection.<RequestAsync>d__7`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.RequestPipeline.<CallElasticsearchAsync>d__66`1.MoveNext()
   at Elasticsearch.Net.ExceptionExtensions.RethrowKeepingStackTrace(Exception exception)
   at Elasticsearch.Net.RequestPipeline.<CallElasticsearchAsync>d__66`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.Transport`1.<RequestAsync>d__15`1.MoveNext()
# Exception:
Elasticsearch.Net.UnexpectedElasticsearchClientException: Invalid JSON string ---> System.Runtime.Serialization.SerializationException: Invalid JSON string
   at Elasticsearch.Net.SimpleJson.DeserializeObject(String json)
   at Elasticsearch.Net.SimpleJson.DeserializeObject(String json, Type type, IJsonSerializerStrategy jsonSerializerStrategy)
   at Elasticsearch.Net.SimpleJson.DeserializeObject[T](String json, IJsonSerializerStrategy jsonSerializerStrategy)
   at Elasticsearch.Net.ElasticsearchDefaultSerializer.<DeserializeAsync>d__3`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.ResponseBuilder`1.<SetBodyAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.ResponseBuilder`1.<ToResponseAsync>d__16.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.HttpConnection.<RequestAsync>d__7`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.RequestPipeline.<CallElasticsearchAsync>d__66`1.MoveNext()
   at Elasticsearch.Net.ExceptionExtensions.RethrowKeepingStackTrace(Exception exception)
   at Elasticsearch.Net.RequestPipeline.<CallElasticsearchAsync>d__66`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at Elasticsearch.Net.Transport`1.<RequestAsync>d__15`1.MoveNext()
   --- End of inner exception stack trace ---
   at Elasticsearch.Net.Transport`1.<RequestAsync>d__15`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at MyCustomElasticClient.<GetAsync>d__a`1.MoveNext() in [removed]\MyCustomElasticClient.cs:line 63
@russcam
Copy link
Contributor

russcam commented Mar 10, 2016

@seanwm, this looks like a good idea, thanks for reporting. Also, nice to see DebugInformation coming in handy here 😄

@gmarz gmarz added Bug labels Mar 14, 2016
@russcam russcam self-assigned this Mar 15, 2016
russcam added a commit that referenced this issue Mar 15, 2016
Fixes #1901
Add ability to set a non-json fixed response and additionally an Exception when creating a FixedReturnClient
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants