ServiceStack: Keep getting HTTP 500 errors for unknown reason - servicestack

All of a sudden, I keep getting HTTP 500 errors in my self-hosted ServiceStack WS.
I have several requests already in place and they are working fine, but this one just wont work. I have added my license like this:
private void StartServiceStackService()
{
Licensing.RegisterLicenseFromFileIfExists("servicestack-license.txt".MapHostAbsolutePath());
_serviceStackHost = new ServiceStackWsHost(this, _frontEndModuleParameters, _alfaWebServicesSettings);
_serviceStackHost.Init();
if (!Debugger.IsAttached)
{
_serviceStackHost.Start(new[] { "http://+:8080/" });
}
else
{
_serviceStackHost.Start(new[] { "http://+:8081/" });
}
}
And the failing service is:
[Route(Bookings.BASE_PATH + "search", Verbs = "GET")]
public class SearchAddress : IReturn<SearchAddressResponse>
{
public string SearchString { get; set; }
}
public class SearchAddressResponse : ResponseBase
{
public string Test { get; set; }
// public List<Address> Addresses { get; set; }
}
internal class SearchAddressHandler : ServiceHandlerBase
{
public SearchAddressResponse Get(SearchAddress searchAddress)
{
return new SearchAddressResponse()
{
Test = "ASDASDASD"
};
}
}
And I call it using Fiddler4 like this:
GET http://192.168.0.147:8081/alfaonline/bookings/search?SearchString=123 HTTP/1.1
User-Agent: Fiddler
Host: 192.168.0.147:8081
AuthToken: a18b613c-23b2-4f4e-8934-ad8d6cbc57bb
DeviceUUID: 1baaace
and get this reply:
HTTP/1.1 500 Internal Server Error
Transfer-Encoding: chunked
Content-Type: text/html
Vary: Accept
Server: Microsoft-HTTPAPI/2.0
X-Powered-By: ServiceStack/5.20 Net45/Windows
Date: Wed, 26 Sep 2018 11:28:31 GMT
0
If I instead return "null", like this:
[MyAuthenticate]
internal class SearchAddressHandler : ServiceHandlerBase
{
public SearchAddressResponse Get(SearchAddress searchAddress)
{
return null;
}
}
Fiddler gives me HTTP 204 OK:
HTTP/1.1 204 OK
Content-Length: 0
Vary: Accept
Server: Microsoft-HTTPAPI/2.0
X-Powered-By: ServiceStack/5.20 Net45/Windows
Date: Wed, 26 Sep 2018 11:26:29 GMT
I see no errors, exceptions in VS in debug mode and "catch all" in Exception settings. I can put a breakpoint in the handler, and it breaks there, so the correct handler is executed.
UPDATE I have always been using Fiddler, now running Fiddler4. When I try the service, described below, in for example swagger (plugin to ServiceStack), it runs as expected. If I run the service in Postman, it runs as expected. But if I run it in Fiddler, I get HTTP 500
UPDATE 2 I also just noticed that going to http://127.0.0.1:8081/requestlogs also yields HTTP 500 error. More specifically, when I access /requestlogs and add the UncaughtExceptionHandlers, I see this error:
System.MissingMethodException: Method not found: 'System.String
ServiceStack.StringUtils.HtmlEncodeLite(System.String)'. at
ServiceStack.Formats.HtmlFormat.d__10.MoveNext()
at
System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[TStateMachine](TStateMachine&
stateMachine) at
ServiceStack.Formats.HtmlFormat.SerializeToStreamAsync(IRequest req,
Object response, Stream outputStream) at
ServiceStack.HttpResponseExtensionsInternal.d__7.MoveNext()

Your first approach should be to get information about the Error:
Include a ResponseStatus property in your Response DTO if not already,
Enable Config.DebugMode
Add Debug Logging
Register Exception Handlers.

Related

How to remove Azure.Storage.Blobs logging from Azure Function App logs?

I have started using Azure.Storage.Blobs nuget in my Function Apps.
Only problem it causes at the moment is that it logs a lot of unnecessary stuff that I don't need to see. Mainly Request and Response messages that fill a large amount of my application insights now.
Is there a way to remove those without touching any other logs? I would assume you should be able to do something from host.json, but so far nothing has worked for me to tackle this problem.
Example logs that I get:
Request [f42fdb4b-8d26-418d-ae67-1d4e79bdabd6] GET <resource_address> x-ms-version:2021-08-06 Accept:application/xml x-ms-client-request-id: x-ms-return-client-request-id:true User-Agent:azsdk-net-Storage.Blobs/12.13.0,(.NET 6.0.8; Microsoft Windows 10.0.14393) x-ms-date:Thu, 29 Sep 2022 19:07:43 GMT Authorization:REDACTED client assembly: Azure.Storage.Blobs
Response [f42fdb4b-8d26-418d-ae67-1d4e79bdabd6] 200 OK (00.0s) Accept-Ranges:bytes ETag:"" Server:Windows-Azure-Blob/1.0,Microsoft-HTTPAPI/2.0 x-ms-request-id: x-ms-client-request-id:<request_id> x-ms-version:2021-08-06 x-ms-version-id:REDACTED x-ms-is-current-version:REDACTED x-ms-creation-time:Thu, 29 Sep 2022 19:07:39 GMT x-ms-lease-status:unlocked x-ms-lease-state:available x-ms-blob-type:BlockBlob x-ms-server-encrypted:true Date:Thu, 29 Sep 2022 19:07:43 GMT Content-Length:222058 Content-Type:application/pdf Content-MD5: Last-Modified:Thu, 29 Sep 2022 19:07:39 GMT Content-Disposition:
In functions where blobs are handled there will be A LOT of request/response logs like these. I tend to wrap my operations with try-catch and log possible errors, so these are completely pointless to write.
I had the same problem when I used QueueTrigger, and my fix is to remove my TelemetryClient from singleton and in dependency injection. It also manages to remove all built-in logs. Example of the code.
public class Function1
{
private readonly TelemetryClient _telemetryClient;
public Function1()
{
_telemetryClient = TelemetryClientHelper.GetInstance();
}
}
public static class TelemetryClientHelper
{
private static TelemetryClient _telemetryClient;
public static TelemetryClient GetInstance()
{
if(_telemetryClient == null)
{
var telemetryConfiguration = TelemetryConfiguration.CreateDefault();
telemetryConfiguration.ConnectionString = Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING");
_telemetryClient = new TelemetryClient(telemetryConfiguration);
}
return _telemetryClient;
}
}

Alexa Reminders API 401 response

So, I am using Amazon Alexa Reminders API as shown here.
Here is my method for sending requests to API:
public static void sendReminder(String accessToken, String reminderText, long offsetInSec) {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost("https://api.amazonalexa.com/v1/alerts/reminders");
post.addHeader("Authorization", "Bearer " + accessToken);
post.addHeader("Content-Type", "application/json");
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());
String jsonContent = "{ \"requestTime\" : \"" + nowAsISO + "\", \"trigger\": { \"type\" : \"SCHEDULED_RELATIVE\", \"offsetInSeconds\" : \"" + offsetInSec + "\" }, \"alertInfo\": { \"spokenInfo\": { \"content\": [{ \"locale\": \"en-US\", \"text\": \"" + reminderText + "\" }] } }, \"pushNotification\" : { \"status\" : \"ENABLED\" } }";
HttpEntity entity = null;
try {
byte[] bytes = jsonContent.getBytes("UTF-8");
entity = new ByteArrayEntity(bytes);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
post.setEntity(entity);
try {
CloseableHttpResponse response = client.execute(post);
System.out.println(response);
} catch (IOException e) {
e.printStackTrace();
}
}
And I execute it like this:
RemindersToolkit.sendReminder(session.getUser().getAccessToken(), "text", 1);
Skill also has permission for reminders:
But when the method is executed, I get the following response:
HttpResponseProxy{HTTP/1.1 401 Unauthorized [Content-Type: application/json, Connection: keep-alive, Server: Server, Date: Tue, 22 Jan 2019 00:21:21 GMT, Vary: Accept-Encoding,User-Agent, x-amz-rid: 8YMCM10GKVGTT71JQH3N, X-Cache: Error from cloudfront, Via: 1.1 05a90e634e0872685ad69ee9a4e0eba5.cloudfront.net (CloudFront), X-Amz-Cf-Id: J5CtMnkUTv1hd6p-7-tob7mCb-4DM7y_LxhEiMLt5x3qEqmzhwbx_Q==] org.apache.http.client.entity.DecompressingEntity#6df97b55}
According to Amazon on this page, 401 UNAUTHORIZED means Token is valid but does not have appropriate permissions.
Maybe some of you guys had the same problem or could help me figure out how to solve mine?
Thanks
Got it worked, as pointed out in this answer, granting permission in the skill is not enough, the end user using that skill also has to grant the permission. Ask the user for the permission through permission card when encountered with the unauthorized response.
The issue was that I was using the old Alexa SDK.
I had to download current version of the SDK and there is a different key (not accessToken I've used), which can be obtained directly from the Intent object and can then be used to send requests

How can I perform this request using Retrofit?

I'm trying to perform a request using Retrofit but I'm getting 404 error whereas it is working using Postman:
Authorization header with value "key=123456789"
Content-Type header with value application/json
and in the body:
{"notification": {"title":"Title","text":"Hello"},"to":"1234"}
The response will be like:
{ "multicast_id": 108,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{ "message_id": "1:08" }
]
}
I have this Retrofit 2 code:
public interface FcmApi {
#POST("/")
#Headers({"Content-Type: application/json", "Authorization: key=123456789"})
Observable<MyResponse> send(#Body String body);
}
MyResponse class
#JsonIgnoreProperties(ignoreUnknown = true)
public class MyResponse {
public int success;
}
and a test:
String json = "{\"notification\": " +
"{\"title\":\"Title\",\"text\":\"Hello\"}," +
"\"to\":\"1234\"}";
api.send(json);
But I get 404 error. Using Postman works properly with the same example.
Seems like you're using key=123456789. You should be using the server key from Firebase Console. Also "to":"1234" should be the real Firebase Registration Id from your device.

Custom OAuth2 server returns 401 - Unathorized

I'm trying to do custom OAuth2 authorization server that will support Resource Owner Password Credentials flow. The authorization server is an WebAPI application hosted in IIS7.5.
I have configured startup class where I register custom OAuthServerProvider (AtcAuthorizationServerProvider).
[assembly: OwinStartup(typeof(ATC.WebApi.AuthorizationServer.Startup))]
namespace ATC.WebApi.AuthorizationServer
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureOAuth(app);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
}
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new AtcAuthorizationServerProvider(),
RefreshTokenProvider = new AtcRefreshTokenProvider(),
AuthenticationMode = AuthenticationMode.Passive
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions(){});
}
}
}
In my custom provider class, I override ValidateClientAuthentication() function where I accept both client credentials receiving ways (in Body and in Authorization header).
public class AtcAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId = string.Empty;
string clientSecret = string.Empty;
// get client credentials from header or from body
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}
//rest of code
Everything works fine when I send client_id and client_secret in body.
POST /ATC.WebApi.AuthorizationServer/token HTTP/1.1
Host: localhost
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
grant_type=password&password=123456&username=myUser&client_id=myClient&client_secret=123%40abc
I get access token successfully.
{
"access_token": "3Fk_Ps10i45uL0zeCzIpvEh2WHKE8iJVNtKJ2XGWcQWXsT9jllKf...",
"token_type": "bearer",
"expires_in": 1799,
"refresh_token": "4c1097d17dd14df5ac1c5842e089a88e",
"as:client_id": "myClient"
}
However, if I use DotNetOpenAuth.OAuth2.WebServerClient which passes client_id and client_secret in Authorization header I will recieve 401.1 - Unauthorized HTTP response. I have found out that the ValidateClientAuthentication() is not fired.
Request than looks like this:
POST /ATC.WebApi.AuthorizationServer/token HTTP/1.1
Host: localhost
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Basic C16b34lUjEyM0BhYmM=
Cache-Control: no-cache
grant_type=password&password=123456&username=myUser
The question is how to persuade probably the OWIN middle-ware firing my custom Provider in this case?
Well, I finally found out where is the trouble. There was Basic authentication allowed in my IIS, so IIS got the request and tried to Authenticate User which failed and IIS returned 401 Unauthorized immediately. So my OWIN middleware even did not receive the request to processing.

ServiceStack How to throw the real httpstatuscode in ExceptionHandler?

i have a SimplaKeyAuthorizeFilter,in the filter,will throw 401
public SimpleKeyAuthorize(IHttpRequest req, IHttpResponse res, object obj, bool isDebugMode){
throw new UnauthorizedAccessException("lack sign info!");
}
in the apphost:
this.ExceptionHandler = (httpReq, httpRes, operationName, ex) =>{
DtoUtils.CreateErrorResponse(httpReq, ex, new ResponseStatus() { ErrorCode = ex.ToErrorCode(), Message = ex.Message });
httpRes.Write(ex.ToErrorCode());
httpRes.EndRequest(skipHeaders:false);
};
........
this.RequestFilters.Add((req,res,obj)=>{
new SimpleKeyAuthorize(req,res,obj,false);
});
but when i call the service,the httpstatuscode is 200,is not 401,why?
HTTP/1.1 200 OK (why not 401?)
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 14 Mar 2014 05:56:30 GMT
Content-Length: 27
UnauthorizedAccessException
This is happening because ServiceStack only maps exceptions to status code within the scope of the service.
Request bindings and filters are considered outside this scope, which is why they trigger a separate exception handler method. See the section Customized Error Handling in the Error Handling documentation.
If you throw an exception here you will need to set the response status code yourself.
httpRes.StatusCode = HttpStatusCode.Unauthorized;
Hope this helps.

Resources