I try to build a parametered middleware, but I only get http 504 error. This code works fine without the parameter
any idea?
public void Configuration(IAppBuilder app)
{
app.Use<MyMiddleware>("Hello");
}
class MyMiddleware : OwinMiddleware
{
public MyMiddleware(OwinMiddleware next, string message)
: base(next)
{
Message = message;
}
public string Message { get; set; }
public override async Task Invoke(IOwinContext context)
{
context.Response.ContentLength = Message.Length;
context.Response.ContentType = "text/html";
await context.Response.WriteAsync(Message);
await Next.Invoke(context);
}
}
Ok I found the issue
ContentLength should be evaluated in Utf-8 like this:
Encoding.UTF8.GetBytes(Message).Length
c# uses utf-16 encoding by default
Related
I want to force https url when http url was requested. I found this in prettyfaces forum. but this code give cannot find symbol error. how can I fix this ?
return ConfigurationBuilder.begin()
.addRule()
.when(URL.captureIn("url").and(Path.matches("/login")).and(Scheme.matches("http")))
.perform(Redirect.permanent(URL.capturedWith("url").toScheme("https")));
Try using a parameter Transposition:
return ConfigurationBuilder.begin()
.addRule()
.when(URL.captureIn("url").and(Path.matches("/login")).and(Scheme.matches("http")))
.perform(Redirect.permanent("{url}"))
.where("url").transposedBy(new Transposition() { ... convert to HTTPS HERE ... });
https://github.com/ocpsoft/rewrite/blob/master/api/src/main/java/org/ocpsoft/rewrite/param/Transposition.java
You can also achieve the same thing by doing something like this with a custom Operation:
https://github.com/ocpsoft/rewrite/blob/master/config-servlet/src/test/java/org/ocpsoft/rewrite/servlet/config/SchemeChangeConfigurationProvider.java
public class SchemeChangeConfigurationProvider extends HttpConfigurationProvider
{
#Override
public int priority()
{
return 0;
}
#Override
public Configuration getConfiguration(final ServletContext context)
{
Configuration config = ConfigurationBuilder.begin()
.addRule().when(Scheme.matches("http")).perform(new HttpOperation() {
#Override
public void performHttp(HttpServletRewrite event, EvaluationContext context)
{
String url = event.getRequest().getRequestURL().toString().replaceFirst("http", "https");
Redirect.temporary(url).perform(event, context);
}
});
return config;
}
}
I am trying to hit the api : www.xyz.com/abc_cc/cc/userregister/newuser
This is my Code :
public class MainActivity extends AppCompatActivity {
public static final String BASE_URL = "abc.com/abc_cc/cc/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getUnsafeOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
Endpoints endpoints= retrofit.create(Endpoints.class);
endpoints.newuser("{\"full_name\":\"sss\",\"states_id\":\"20\",\"mobile\":\"9876543210\",\"password\":\"******\",\"accept_terms\":true,\"Userid\":\"0\",\"refer\":\"\",\"ip-address\":\"1.2.3.4\",\"device_type\":\"samsung J5\",\"os-version\":\"5.0.1\",\"client\":\"app\",\"secret_key\":\"44\"}")
.enqueue(new retrofit2.Callback<Items>() {
#Override
public void onResponse(retrofit2.Call<Items> call, retrofit2.Response<Items> response) {
System.out.println("onResponse : "+response.message());
System.out.println("onResponse : "+response.body());
System.out.println("onResponse : "+response.code());
System.out.println("onResponse : "+response.errorBody());
System.out.println("onResponse : "+response.isSuccessful());
System.out.println("onResponse : "+response.raw());
System.out.println("onResponse : "+response);
}
#Override
public void onFailure(retrofit2.Call<Items> call, Throwable t) {
System.out.println("onFailure"+call);
}
});
}
public static OkHttpClient getUnsafeOkHttpClient() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
} };
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts,
new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext
.getSocketFactory();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient = okHttpClient.newBuilder()
.sslSocketFactory(sslSocketFactory)
.hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Interface :
public interface Endpoints {
#POST("/userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}
POJO class :
public class Items {
#SerializedName("Response-Status")
#Expose
private Boolean responseStatus;
#SerializedName("Response-Validate")
#Expose
private Boolean responseValidate;
#SerializedName("Response-Message")
#Expose
private String responseMessage;
#SerializedName("Response-Data")
#Expose
private ResponseData responseData;
public Boolean getResponseStatus() {
return responseStatus;
}
public void setResponseStatus(Boolean responseStatus) {
this.responseStatus = responseStatus;
}
public Boolean getResponseValidate() {
return responseValidate;
}
public void setResponseValidate(Boolean responseValidate) {
this.responseValidate = responseValidate;
}
public String getResponseMessage() {
return responseMessage;
}
public void setResponseMessage(String responseMessage) {
this.responseMessage = responseMessage;
}
public ResponseData getResponseData() {
return responseData;
}
public void setResponseData(ResponseData responseData) {
this.responseData = responseData;
}
}
I am getting this response :
{protocol=http/1.1, code=404, message=Not Found, url=www.xyz.com/userregister/newuser}
I have given the proper url then why is it taking only half of it?
I have tried the example from https://code.tutsplus.com/tutorials/sending-data-with-retrofit-2-http-client-for-android--cms-27845. This example and the link given in the example are working fine, but if I do the same with my url then I get the above error
I Hope kindly check your parsing issues may occurred.
#Override
public void onFailure(retrofit2.Call<Items> call, Throwable t) {
System.out.println("onFailure"+call);
//add this lije you got exceptions.
t.printStackTrace();
}
Change your Endpoints interface for this:
public interface Endpoints {
#POST("userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}
Note that I removed the trailing slash /. This way Retrofit appends the path you defined to the BASE_URL.
refer to the docs for Retrofit.Builder for a more detailed explanation, but pay particular attention to these bits:
Base URLs should always end in /.
A trailing / ensures that endpoints values which are relative paths
will correctly append themselves to a base which has path components.
...
Endpoint values which contain a leading / are absolute.
Absolute values retain only the host from baseUrl and ignore any
specified path components.
as presently written, the path referenced in your call to Endpoints.newuser() is absolute, and therefore the path segments after the host in your base URL are dropped (as this is the documented behavior).
therefore, you should change your Endpoints interface to use relative paths instead, like so:
public interface Endpoints {
#POST("userregister/newuser")
#FormUrlEncoded
Call<Items> newuser(#Field("Data") String Data);
}
I am trying to implement service gateway pattern according to Service Gateway tutorial to support in-process handing via InProcessServiceGateway and external calling via JsonServiceClient in case ServiceStack service is deployed standalone. I use ServiceStack 4.5.8 version.
Validation feature works fine, but with InProcessServiceGateway, the failed validation throws ValidationException which directly results in a ServiceStack.FluentValidation.ValidationException in the client rather than populating ResponseStatus property of MyResponseDto. And I also tried GlobalRequestFilters and ServiceExceptionHandlers, both of them seem to work fine to capture ValidationException only with JsonHttpClient but InProcessServiceGateway.
Is there any way to make ValidationException thrown by InProcessServiceGateway captured and translated into Dto's ResponseStatus? Thanks.
My AppHost:
//Register CustomServiceGatewayFactory
container.Register<IServiceGatewayFactory>(x => new CustomServiceGatewayFactory()).ReusedWithin(ReuseScope.None);
//Validation feature
Plugins.Add(new ValidationFeature());
//Note: InProcessServiceGateway cannot reach here.
GlobalRequestFilters.Add((httpReq, httpRes, requestDto) =>
{
...
});
//Note: InProcessServiceGateway cannot reach here.
ServiceExceptionHandlers.Add((httpReq, request, ex) =>
{
...
});
My CustomServiceGatewayFactory:
public class CustomServiceGatewayFactory : ServiceGatewayFactoryBase
{
private IRequest _req;
public override IServiceGateway GetServiceGateway(IRequest request)
{
_req = request;
return base.GetServiceGateway(request);
}
public override IServiceGateway GetGateway(Type requestType)
{
var standaloneHosted = false;
var apiBaseUrl = string.Empty;
var apiSettings = _req.TryResolve<ApiSettings>();
if (apiSettings != null)
{
apiBaseUrl = apiSettings.ApiBaseUrl;
standaloneHosted = apiSettings.StandaloneHosted;
}
var gateway = !standaloneHosted
? (IServiceGateway)base.localGateway
: new JsonServiceClient(apiBaseUrl)
{
BearerToken = _req.GetBearerToken()
};
return gateway;
}
}
My client base controller (ASP.NET Web API):
public virtual IServiceGateway ApiGateway
{
get
{
var serviceGatewayFactory = HostContext.AppHost.TryResolve<IServiceGatewayFactory>();
var serviceGateway = serviceGatewayFactory.GetServiceGateway(HttpContext.Request.ToRequest());
return serviceGateway;
}
}
My client controller action (ASP.NET Web API):
var response = ApiGateway.Send<UpdateCustomerResponse>(new UpdateCustomer
{
CustomerGuid = customerGuid,
MobilePhoneNumber = mobilePhoneNumber
ValidationCode = validationCode
});
if (!response.Success)
{
return this.Error(response, response.ResponseStatus.Message);
}
My UpdateCustomer request DTO:
[Route("/customers/{CustomerGuid}", "PUT")]
public class UpdateCustomer : IPut, IReturn<UpdateCustomerResponse>
{
public Guid CustomerGuid { get; set; }
public string MobilePhoneNumber { get; set; }
public string ValidationCode { get; set; }
}
My UpdateCustomerValidator:
public class UpdateCustomerValidator : AbstractValidator<UpdateCustomer>
{
public UpdateCustomerValidator(ILocalizationService localizationService)
{
ValidatorOptions.CascadeMode = CascadeMode.StopOnFirstFailure;
RuleFor(x => x.ValidationCode)
.NotEmpty()
.When(x => !string.IsNullOrWhiteSpace(x.MobilePhoneNumber))
.WithErrorCode(((int)ErrorCode.CUSTOMER_VALIDATIONCODE_EMPTY).ToString())
.WithMessage(ErrorCode.CUSTOMER_VALIDATIONCODE_EMPTY.GetLocalizedEnum(localizationService, Constants.LANGUAGE_ID));
}
}
My UpdateCustomerResponse DTO:
public class UpdateCustomerResponse
{
/// <summary>
/// Return true if successful; return false, if any error occurs.
/// </summary>
public bool Success { get; set; }
/// <summary>
/// Represents error details, populated only when any error occurs.
/// </summary>
public ResponseStatus ResponseStatus { get; set; }
}
ServiceStack 4.5.8's InProcessServiceGateway source code:
private TResponse ExecSync<TResponse>(object request)
{
foreach (var filter in HostContext.AppHost.GatewayRequestFilters)
{
filter(req, request);
if (req.Response.IsClosed)
return default(TResponse);
}
if (HostContext.HasPlugin<ValidationFeature>())
{
var validator = ValidatorCache.GetValidator(req, request.GetType());
if (validator != null)
{
var ruleSet = (string)(req.GetItem(Keywords.InvokeVerb) ?? req.Verb);
var result = validator.Validate(new ValidationContext(
request, null, new MultiRuleSetValidatorSelector(ruleSet)) {
Request = req
});
if (!result.IsValid)
throw new ValidationException(result.Errors);
}
}
var response = HostContext.ServiceController.Execute(request, req);
var responseTask = response as Task;
if (responseTask != null)
response = responseTask.GetResult();
return ConvertToResponse<TResponse>(response);
}
ServiceStack's Service Gateways now convert validation exceptions into WebServiceExceptions from this commit which is available from v4.5.13 that's now available on MyGet.
I am new to TDD and RhinoMocks.
I am trying to test AssertWasCalled but having problems. The constructor to my test is as follows:
public AccountControllerTests()
{
_webAuthenticator = MockRepository.GenerateMock<IWebAuthenticator>();
}
And my test is like this:
[TestMethod]
public void AccountControllerCallsWebAuthenticator_CreateSignInTicketForGoodLoginCredentials()
{
const string username = "good-username";
const string password = "good-password";
var model = new LoginModel { Username = username, Password = password };
_webAuthenticator.Stub(w => w.Authenticate(username, password)).Return(true);
var mockHttpContextBase = MockRepository.GenerateMock<HttpContextBase>();
var accountController = new AccountController(_webAuthenticator);
accountController.Login(model);
_webAuthenticator.AssertWasCalled(x => x.CreateSignInTicket(mockHttpContextBase, username));
}
The error I get is:
Test method Paxium.Music.WebUI.Tests.Controllers.AccountControllerTests.AccountControllerCallsWebAuthenticator_CreateSignInTicketForGoodLoginCredentials threw exception:
Rhino.Mocks.Exceptions.ExpectationViolationException: IWebAuthenticator.CreateSignInTicket(Castle.Proxies.HttpContextBaseProxy7f274f09b6124e6da32d96dc6d3fface, "good-username"); Expected #1, Actual #0.
I have now changed my code as below - Before and after code:
Before:
public class AccountController : Controller
{
private readonly IWebAuthenticator _webAuthenticator;
public AccountController(IWebAuthenticator webAuthenticator)
{
_webAuthenticator = webAuthenticator;
}
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
if (_webAuthenticator.Authenticate(model.Username, model.Password))
{
_webAuthenticator.CreateSignInTicket(HttpContext, model.Username);
return RedirectToAction("Index", "Home");
}
return View(model);
}
return View(model);
}
}
After:
public class AccountController : Controller
{
private readonly IWebAuthenticator _webAuthenticator;
private readonly HttpContextBase _contextBase;
public AccountController()
{
}
public AccountController(IWebAuthenticator webAuthenticator, HttpContextBase contextBase)
{
_webAuthenticator = webAuthenticator;
_contextBase = contextBase;
}
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
if (_webAuthenticator.Authenticate(model.Username, model.Password))
{
_webAuthenticator.CreateSignInTicket(_contextBase, model.Username);
return RedirectToAction("Index", "Home");
}
return View(model);
}
return View(model);
}
}
My tests now pass. How I inject in the contextBase though when my controller is used for real?? I am using StructureMap.
The error message you are receiving indicates that the Assert failed, i.e. the webAuthenticator object was not called with those specific arguments (hence expected #1, actual #0 exception message).
From the limited context you provide, I suspect that the fake instance of the HttpContextBase (mockHttpContextBase) in your test is not the same object that's being passed to the webAuthenticator from your production code.
There's two ways you can go about this: make the assert less strict or make sure the production code uses the fake http context object. If you don't care which instance of HttpContext gets passed to the webAuthenticator in this test, you can use argument matchers (Rhinomocks calls them argument constraints).
In your case, this would turn out something like this:
_webAuthenticator.AssertWasCalled(x => x.CreateSignInTicket(Arg<HttpContextBase>.Is.Anything, Arg<string>.Is.Equal(username)));
I know I can manage the routes for the REST-ful interface operations by attributing the DTOs
[Route("/widgets", "GET, POST")]
[DataContract()]
public class GetWidgetsRequest
{
[DataMember]
public string OutletCode { get; set; }
[DataMember]
public IList<Specification> WidgetsCaptured { get; set; }
}
but I have searched and experimented unsuccessfully at trying to affect the default /soap11 appendage to the endpoint for a given SOAP operation.
**POST /soap11 HTTP/1.1**
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: nnn
SOAPAction: GetItemsRequest
A broader question within the question is, what are my options and how to configure the different endpoint settings?
Thanks!
Please read the SOAP Support docs for guidelines and limitations of using SOAP in ServiceStack.
For a different SOAP path, eg ~/services, you can add your own servicestack plugin , that returns your own servicestack soap handler.
public class MySoapFeature : IPlugin
{
private static IHttpHandler GetHandlerForPathParts(string[] pathParts)
{
string str2 = string.Intern(pathParts[0].ToLower());
if (pathParts.Length != 1) return null;
if (str2 == "services")
{
return new MySoapHttpHandler();
}
return null;
}
public IHttpHandler ProcessRequest(string httpMethod, string pathInfo, string filePath)
{
char[] chrArray = new char[] { '/' };
string[] strArrays = pathInfo.TrimStart(chrArray).Split(new char[] { '/' });
if ((int)strArrays.Length == 0)
{
return null;
}
return MySoapFeature.GetHandlerForPathParts(strArrays);
}
public void Register(IAppHost appHost)
{
appHost.CatchAllHandlers.Add(this.ProcessRequest);
}
}
Then implement this handler based on Soap11Handler or Soap12Handler
public class MySoapHttpHandler : Soap11Handler, IHttpHandler
{
public MySoapHttpHandler()
: base((EndpointAttributes)((long)32768))
{
}
public new void ProcessRequest(HttpContext context)
{
if (context.Request.HttpMethod == "GET")
{
(new Soap11WsdlMetadataHandler()).Execute(context);
return;
}
Message message = base.Send(null);
context.Response.ContentType = base.GetSoapContentType(context.Request.ContentType);
using (XmlWriter xmlWriter = XmlWriter.Create(context.Response.OutputStream))
{
message.WriteMessage(xmlWriter);
}
}
public override void ProcessRequest(IHttpRequest httpReq, IHttpResponse httpRes, string operationName)
{
if (httpReq.HttpMethod == "GET")
{
(new Soap11WsdlMetadataHandler()).Execute(httpReq, httpRes);
return;
}
Message message = base.Send(null, httpReq, httpRes);
httpRes.ContentType = base.GetSoapContentType(httpReq.ContentType);
using (XmlWriter xmlWriter = XmlWriter.Create(httpRes.OutputStream))
{
message.WriteMessage(xmlWriter);
}
}
Then register your plugin in the servicestack apphost Configure()
Plugins.Add(new MySoapFeature());
Then create your Dto classes for the request and response. Have "Response" added to the response dto class name. Do NOT put a Route attribute on the request Dto, as it gets routed by the Soap method name in the Xml.
[DataContract(Namespace = "http://mynamespace/schemas/blah/1.0")]
public class MySoapMethod
{}
DataContract(Namespace = "http://mynamespace/schemas/blah/1.0")]
public class MySoapMethodResponse
{
[DataMember]
public string SomeProperty { get; set; }
}
Then have a Service to implement the Soap Dto's
public class SOAPService : Service
{
public MySoapMethodResponse Post(MySoapMethod request)
{
var response = new MySoapMethodResponse();
response.SomeProperty = "blah";
return response;
}
}