Rectangle 27 6

Status Code 304 Not Modified would also make an acceptable response to a duplicate request. This is similar to processing a header of If-None-Match using an entity tag.

In my opinion, @Piskvor's answer is the more obvious choice to what I perceive is the intent of the original question, but I have an alternative that is also relevant.

If you want to treat a duplicate request as a warning or notification rather than as an error, a response status code of 304 Not Modified and Content-Location header identifying the existing resource would be just as valid. When the intent is merely to ensure that a resource exists, a duplicate request would not be an error but a confirmation. The request is not wrong, but is simply redundant, and the client can refer to the existing resource.

In other words, the request is good, but since the resource already exists, the server does not need to perform any further processing.

It was my understanding that 304 is intended for GET operations to assist with caching.

REST HTTP status codes for failed validation or invalid duplicate - St...

http rest http-status-codes
Rectangle 27 6

Status Code 304 Not Modified would also make an acceptable response to a duplicate request. This is similar to processing a header of If-None-Match using an entity tag.

In my opinion, @Piskvor's answer is the more obvious choice to what I perceive is the intent of the original question, but I have an alternative that is also relevant.

If you want to treat a duplicate request as a warning or notification rather than as an error, a response status code of 304 Not Modified and Content-Location header identifying the existing resource would be just as valid. When the intent is merely to ensure that a resource exists, a duplicate request would not be an error but a confirmation. The request is not wrong, but is simply redundant, and the client can refer to the existing resource.

In other words, the request is good, but since the resource already exists, the server does not need to perform any further processing.

It was my understanding that 304 is intended for GET operations to assist with caching.

REST HTTP status codes for failed validation or invalid duplicate - St...

http rest http-status-codes
Rectangle 27 6

Status Code 304 Not Modified would also make an acceptable response to a duplicate request. This is similar to processing a header of If-None-Match using an entity tag.

In my opinion, @Piskvor's answer is the more obvious choice to what I perceive is the intent of the original question, but I have an alternative that is also relevant.

If you want to treat a duplicate request as a warning or notification rather than as an error, a response status code of 304 Not Modified and Content-Location header identifying the existing resource would be just as valid. When the intent is merely to ensure that a resource exists, a duplicate request would not be an error but a confirmation. The request is not wrong, but is simply redundant, and the client can refer to the existing resource.

In other words, the request is good, but since the resource already exists, the server does not need to perform any further processing.

It was my understanding that 304 is intended for GET operations to assist with caching.

REST HTTP status codes for failed validation or invalid duplicate - St...

http rest http-status-codes
Rectangle 27 30

406 Not Acceptable The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.

406 happens when the server cannot respond with the accept-header specified in the request. In your case it seems application/json for the response may not be acceptable to the server.

if i remove the header i am getting an error........

You don't have remove the header, you will have to supply a different one which is acceptable to the server. en.wikipedia.org/wiki/

json - What is "406-Not Acceptable Response" in HTTP? - Stack Overflow

json api http rest
Rectangle 27 11

The Accept request-header field can be used to specify certain media types which are acceptable for the response.

This means that the header is optional because it says can be used.

as you pointed out ther RFC also says:

If no Accept header field is present, then it is assumed that the client accepts all media types.

This means that omitting the header SHOULD be equivalently interpreted by the server as sending Accept: */* in the sense that the client acceptes all media types in both cases.

It is interesting that the facebook response differs in both cases but I guess it is their failure of interpreting the protocol correctly. Though on the other side both responses are obviously correct responses to the request (Which I find a funny twist).

I have some general thoughts on this issue (which might also contribute to the bugfix discussion):

Be conservative in what you do, be liberal in what you accept from others (often reworded as "Be conservative in what you send, be liberal in what you accept").
Accept: */*
  • Just adding header fields like Accept: */* which could be omitted increases network traffic by 11 Byte for every single request which might lead to performance issues. Having Accept: */* be default in the request might make it hard for developers to get it out of the header in order to save to 11 Byte.
  • There is a difference between a specification (or a standard) and a de facto standard. Obviously omitting the header field is perfect according to the specification on the other hand a lot of libraries seem to include this and services like the facebook API behave differently this can be seen as a de facto standard being created and you could jump into the loop and be part of creating it.

When speaking HTTP/1.1: Even though (1) und (3) speak for fixing the urllib I would probably follow the specification and the performance argument (2) and omit the header. As stated above the response of facebook in both cases is correct since they are allowed to set the media type to whatever they like. (even though this behaviour seems unintended, weird, and by mistake)

When speaking HTTP/1.0: I would send the accept header since you said it is not specified in the HTTP/1.0 RFC and then I think Postel's law becomes more important. On the other side the Accept header is just optional in http 1.0. The Accept request-header field can be used to indicate a list of media ranges which are acceptable as a response to the request Why would you set an optional header by default?

Bear in mind,"de facto" standards are great when there are no standards ruling. If there is a standard, there is no such a thing as a "de facto" standard, as anything not conforming with the standard is just a violation (an things conforming are just standard). This problem domain we are talking has a ruling standard. Let's just conform to it.

IMO in an RFC, "can" should not automatically be interpreted to "optional", as you are implying. There are key words like "MAY/MUST" for that. So I don't believe your first interpretation is a valid one, though the second quote does backs the optional case. This comment is not to say that that this answer is wrong. Based on the evidence provided, it seems it is optional. All I'm saying is that you should be careful how you interpret "can". That first quote alone, without more context, is ambiguous.

python - Is it a bug to omit an Accept */* header in an HTTP/1.0 Reque...

python rest http curl http-headers
Rectangle 27 11

The Accept request-header field can be used to specify certain media types which are acceptable for the response.

This means that the header is optional because it says can be used.

as you pointed out ther RFC also says:

If no Accept header field is present, then it is assumed that the client accepts all media types.

This means that omitting the header SHOULD be equivalently interpreted by the server as sending Accept: */* in the sense that the client acceptes all media types in both cases.

It is interesting that the facebook response differs in both cases but I guess it is their failure of interpreting the protocol correctly. Though on the other side both responses are obviously correct responses to the request (Which I find a funny twist).

I have some general thoughts on this issue (which might also contribute to the bugfix discussion):

Be conservative in what you do, be liberal in what you accept from others (often reworded as "Be conservative in what you send, be liberal in what you accept").
Accept: */*
  • Just adding header fields like Accept: */* which could be omitted increases network traffic by 11 Byte for every single request which might lead to performance issues. Having Accept: */* be default in the request might make it hard for developers to get it out of the header in order to save to 11 Byte.
  • There is a difference between a specification (or a standard) and a de facto standard. Obviously omitting the header field is perfect according to the specification on the other hand a lot of libraries seem to include this and services like the facebook API behave differently this can be seen as a de facto standard being created and you could jump into the loop and be part of creating it.

When speaking HTTP/1.1: Even though (1) und (3) speak for fixing the urllib I would probably follow the specification and the performance argument (2) and omit the header. As stated above the response of facebook in both cases is correct since they are allowed to set the media type to whatever they like. (even though this behaviour seems unintended, weird, and by mistake)

When speaking HTTP/1.0: I would send the accept header since you said it is not specified in the HTTP/1.0 RFC and then I think Postel's law becomes more important. On the other side the Accept header is just optional in http 1.0. The Accept request-header field can be used to indicate a list of media ranges which are acceptable as a response to the request Why would you set an optional header by default?

Bear in mind,"de facto" standards are great when there are no standards ruling. If there is a standard, there is no such a thing as a "de facto" standard, as anything not conforming with the standard is just a violation (an things conforming are just standard). This problem domain we are talking has a ruling standard. Let's just conform to it.

IMO in an RFC, "can" should not automatically be interpreted to "optional", as you are implying. There are key words like "MAY/MUST" for that. So I don't believe your first interpretation is a valid one, though the second quote does backs the optional case. This comment is not to say that that this answer is wrong. Based on the evidence provided, it seems it is optional. All I'm saying is that you should be careful how you interpret "can". That first quote alone, without more context, is ambiguous.

python - Is it a bug to omit an Accept */* header in an HTTP/1.0 Reque...

python rest http curl http-headers
Rectangle 27 24

It is perfectly acceptable to specify a response body and use the Location header at the same time. When using the Location header with a 201 response, you're not redirecting the client, you're just telling it where it can find the resource in future.

The W3C docs for this explain further, though the text is actually quite ambiguous:

The Location response-header field is used to redirect the recipient to a location other than the Request-URI for completion of the request or identification of a new resource. For 201 (Created) responses, the Location is that of the new resource which was created by the request. For 3xx responses, the location SHOULD indicate the server's preferred URI for automatic redirection to the resource.

I read that as saying "...redirect... or... identif[y]... new resource", but it's not exactly a plain English sentence.

What is the answer? is it "in a word, no" or "you can specify a response body and use the Location header at the same time"?

I was replying to the question at the end of the body text, not the question in the title.

I was thinking on the same lines. Just wanted to make doubly sure. Thanks Rob.

wondered that also; suggest a rephrase

Is HTTP POST request allowed to send back a response body? - Stack Ove...

http
Rectangle 27 4

  • No control over http response, headers, code, etc - all set by the framework in case of success or failure, return type is visible to run-time tools

You shouldn't have to use dynamic ever, if you need to return arbitrary responses from an action, you can use

  • Better control over the http response, but it will tie up the thread while executing the method, no definition for the output data type

The request thread will be kept up for the duration of the action yes. But if you do not use any async operations (DB Access, a network connection to another website/webservice or read/write files to database), using it is fine.

// Here no async operations are called, so Task is not necessary
public IActionResult Index(string name = _defaultName)
{
    if(!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    return Ok();
}
Task<IActionResult>
  • Better control over http response, will not tie up the thread while executing the method, but will spin off another thread to compute the result, and no definition for the output type

This assumption is just wrong. Using Task alone with true async operations (I/O operations like reading from filesystem, network connections or access to database) will NOT SPAWN a new thread. The operation will be started and the thread returned to the thread pool.

No new thread will be started instead. When the async operation completes, a thread will be taken from the thread pool and operation continues.

// No extra thread is called and the request thread is only 
// used in between "await" calls
public async Task<IActionResult> Get(string name = _defaultName)
{
    var result = await GetResultFromDatabase();

    return Ok(someModel);
}

Please read the Async Programming : Introduction to Async/Await on ASP.NET article on MSDN from Stephen Cleary. It is about ASP.NET MVC 5 (the old webstack, not the rewrite ASP.NET Core) but the principle still applies to ASP.NET Core.

If you have CPU bound operation (calculating some complicated math etc.), then do not start a new thread. This will mess up with how ASP.NET Core manages the thread pool and you will gain nothing, but will still have the overhead of context-switches and hence it will lower your performance instead of increasing it.

For CPU bound operation, simply runt hem synchronously on the request thread.

public IActionResult Get(string name = _defaultName)
{
    // Don't await or run CPU intensive stuff via Task.Run
    var result = SomeCpuIntensiveOperation();

    return Ok(result);
}

You can also mix CPU bound and async operations

public async Task<IActionResult> Get(string name = _defaultName)
{
    // runs async, no extra thread
    var valueFromDb = await GetValueFromDb();

    // Don't await or run CPU intensive stuff via Task.Run
    // runs sync, on request thread
    var result = SomeCpuIntensiveOperation(valueFromDb);

    return Ok(result);
}

I am wondering whether it makes sense without such downstream async dependencies to pursue async webapi methods and the resulting a tad weird looking code.

Generally, async scales better, when you have more requests than available threads in the thread pool. But most small sized applications never reach that state, especially when it's an learning exercise or a proof of concept.

It's very unlikely you hit that limit unless you have a high-traffic website which handles 100s or 1000s of requests per second.

Thank you for the feedback! "You shouldn't have to use dynamic ever" - it was not really a question about (not) using dynamic, unless you could share specific feedback on observed performance impact using dynamic in high-volume web/api apps. I am looking into poc for 10,000+ req/sec micro-services. Scalability is very important and ideally I am looking for a sound generic practice to recommend moving forward, e.g. use async Task<IActionResult> in use-cases a & b, and use IActionResult in use-cases d & e.

No idea about performance of dynamic, just test it. returning Dynamic or concrete type is same, in the end all of them will be wrapped around a IActionResult anyways. IActionResult is not only for http codes, but also for converting or processing the result stream. i.e. PhysicalFileResult will return a file as stream back to the client. As mentioned above, use IActionResult when you don't do async operations or cpu bound operations only.

Use Task<IActionResult> in all true async operations. Allocating/awaiting a task has a slight overhead (allocation of Task class and creation of a state machine when using await). In the end, you will have to do performance tests to decide it finally and it can't be answered here. The above explains how to use Task/async correctly in ASP.NET and ASP.NET Core. The most important correction of your assumption is that awaiting real Task do not spawn new thread and hence do not involve the "expensiveness" of starting a new thread!

c# - .net (dotnet) core webapi and async method - feedback wanted - St...

c# asynchronous asp.net-web-api asp.net-core .net-core
Rectangle 27 465

The content type is a header of the content, not of the request, which is why this is failing. AddWithoutValidation as suggested by Robert Levy may work, but you can also use set the content type when creating the request content itself (note that code snippet adds "application/json" in two places-for Accept and Content-Type headers):

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://example.com/");
client.DefaultRequestHeaders
      .Accept
      .Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("{\"name\":\"John Doe\",\"age\":33}",
                                    Encoding.UTF8, 
                                    "application/json");//CONTENT-TYPE header

client.SendAsync(request)
      .ContinueWith(responseTask =>
      {
          Console.WriteLine("Response: {0}", responseTask.Result);
      });

Alternatively, Response.Content.Headers will work most of the time.

Not working for me. My requiremnt is same, my i written same but not working for me. :(

@AshishJain Most of the SO answers I've seen involving Response.Content.Headers for the ASP.Net Web API haven't worked either, but you can easily set it using HttpContext.Current.Response.ContentType if you need to.

Content-Type is a property of an HTTP message with payload; it has nothing to do with request vs response.

c# - How do you set the Content-Type header for an HttpClient request?...

c# asp.net api http rest
Rectangle 27 442

The content type is a header of the content, not of the request, which is why this is failing. AddWithoutValidation as suggested by Robert Levy may work, but you can also use set the content type when creating the request content itself (note that code snippet adds "application/json" in two places-for Accept and Content-Type headers):

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://example.com/");
client.DefaultRequestHeaders
      .Accept
      .Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("{\"name\":\"John Doe\",\"age\":33}",
                                    Encoding.UTF8, 
                                    "application/json");//CONTENT-TYPE header

client.SendAsync(request)
      .ContinueWith(responseTask =>
      {
          Console.WriteLine("Response: {0}", responseTask.Result);
      });

Alternatively, Response.Content.Headers will work most of the time.

Not working for me. My requiremnt is same, my i written same but not working for me. :(

@AshishJain Most of the SO answers I've seen involving Response.Content.Headers for the ASP.Net Web API haven't worked either, but you can easily set it using HttpContext.Current.Response.ContentType if you need to.

Content-Type is a property of an HTTP message with payload; it has nothing to do with request vs response.

c# - How do you set the Content-Type header for an HttpClient request?...

c# asp.net api http rest
Rectangle 27 442

The content type is a header of the content, not of the request, which is why this is failing. AddWithoutValidation as suggested by Robert Levy may work, but you can also use set the content type when creating the request content itself (note that code snippet adds "application/json" in two places-for Accept and Content-Type headers):

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://example.com/");
client.DefaultRequestHeaders
      .Accept
      .Add(new MediaTypeWithQualityHeaderValue("application/json"));//ACCEPT header

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "relativeAddress");
request.Content = new StringContent("{\"name\":\"John Doe\",\"age\":33}",
                                    Encoding.UTF8, 
                                    "application/json");//CONTENT-TYPE header

client.SendAsync(request)
      .ContinueWith(responseTask =>
      {
          Console.WriteLine("Response: {0}", responseTask.Result);
      });

Alternatively, Response.Content.Headers will work most of the time.

Not working for me. My requiremnt is same, my i written same but not working for me. :(

@AshishJain Most of the SO answers I've seen involving Response.Content.Headers for the ASP.Net Web API haven't worked either, but you can easily set it using HttpContext.Current.Response.ContentType if you need to.

Content-Type is a property of an HTTP message with payload; it has nothing to do with request vs response.

c# - How do you set the Content-Type header for an HttpClient request?...

c# asp.net api http rest
Rectangle 27 1

Set the HTTP response code http_response_code(415); // Unsupported Media Type or http_response_code(415); // Not Acceptable

function showError($message)
    {
        http_response_code(415);
        die($message);
    }

javascript - How to show a custom error message in DropzoneJS? - Stack...

javascript dropzone.js
Rectangle 27 2

If the origin server does not wish to accept the credentials sent
with a request, it SHOULD return a 401 (Unauthorized) response. The
response MUST include a WWW-Authenticate header field containing at
least one (possibly new) challenge applicable to the requested
resource. If a proxy does not accept the credentials sent with a
request, it SHOULD return a 407 (Proxy Authentication Required). The
response MUST include a Proxy-Authenticate header field containing a
(possibly new) challenge applicable to the proxy for the requested
resource.

So, when a client gets a 401 response, can it always assume it is an auth failure on the origin server? Likewise, if it gets a 407, can it always assume it is from a proxy?

According to spec - yes, but I don't work with wide range of web/application servers and proxies to provide example of exception from rule...

HTTP Response Code for Proxy Authorization Failure - Stack Overflow

http http-status-codes http-status-code-401 http-status-code-407
Rectangle 27 4

You can use a custom message inspector to add the Vary header to the responses. Based on the automatic formatting rules for WCF WebHTTP, the order is 1) Accept header; 2) Content-Type of request message; 3) default setting in the operation and 4) default setting in the behavior itself. Only the first two are dependent on the request (thus influencing the Vary header), and for your scenario (caching), only GET are interesting, so we can discard the incoming Content-Type as well. So writing such an inspector is fairly simple: if the AutomaticFormatSelectionEnabled property is set, then we add the Vary: Accept header for the responses of all GET requests - the code below does that. If you want to include the content-type (for non-GET requests as well), you can modify the inspector to look at the incoming request as well.

public class Post_0acbfef2_16a3_440a_88d6_e0d7fcf90a8e
{
    [DataContract(Name = "Person", Namespace = "")]
    public class Person
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public int Age { get; set; }
    }
    [ServiceContract]
    public class MyContentNegoService
    {
        [WebGet(ResponseFormat = WebMessageFormat.Xml)]
        public Person ResponseFormatXml()
        {
            return new Person { Name = "John Doe", Age = 33 };
        }
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        public Person ResponseFormatJson()
        {
            return new Person { Name = "John Doe", Age = 33 };
        }
        [WebGet]
        public Person ContentNegotiated()
        {
            return new Person { Name = "John Doe", Age = 33 };
        }
        [WebInvoke]
        public Person ContentNegotiatedPost(Person person)
        {
            return person;
        }
    }
    class MyVaryAddingInspector : IEndpointBehavior, IDispatchMessageInspector
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            WebHttpBehavior webBehavior = endpoint.Behaviors.Find<WebHttpBehavior>();
            if (webBehavior != null && webBehavior.AutomaticFormatSelectionEnabled)
            {
                endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
            }
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            HttpRequestMessageProperty prop;
            prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
            if (prop.Method == "GET")
            {
                // we shouldn't cache non-GET requests, so only returning this for such requests
                return "Accept";
            }

            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            string varyHeader = correlationState as string;
            if (varyHeader != null)
            {
                HttpResponseMessageProperty prop;
                prop = reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
                if (prop != null)
                {
                    prop.Headers[HttpResponseHeader.Vary] = varyHeader;
                }
            }
        }
    }
    public static void SendGetRequest(string uri, string acceptHeader)
    {
        SendRequest(uri, "GET", null, null, acceptHeader);
    }
    public static void SendRequest(string uri, string method, string contentType, string body, string acceptHeader)
    {
        Console.Write("{0} request to {1}", method, uri.Substring(uri.LastIndexOf('/')));
        if (contentType != null)
        {
            Console.Write(" with Content-Type:{0}", contentType);
        }

        if (acceptHeader == null)
        {
            Console.WriteLine(" (no Accept header)");
        }
        else
        {
            Console.WriteLine(" (with Accept: {0})", acceptHeader);
        }

        HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
        req.Method = method;
        if (contentType != null)
        {
            req.ContentType = contentType;
            Stream reqStream = req.GetRequestStream();
            byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
            reqStream.Write(bodyBytes, 0, bodyBytes.Length);
            reqStream.Close();
        }

        if (acceptHeader != null)
        {
            req.Accept = acceptHeader;
        }

        HttpWebResponse resp;
        try
        {
            resp = (HttpWebResponse)req.GetResponse();
        }
        catch (WebException e)
        {
            resp = (HttpWebResponse)e.Response;
        }

        Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
        foreach (string headerName in resp.Headers.AllKeys)
        {
            Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
        }
        Console.WriteLine();
        Stream respStream = resp.GetResponseStream();
        Console.WriteLine(new StreamReader(respStream).ReadToEnd());

        Console.WriteLine();
        Console.WriteLine("  *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*  ");
        Console.WriteLine();
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(MyContentNegoService), new Uri(baseAddress));
        ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(MyContentNegoService), new WebHttpBinding(), "");
        endpoint.Behaviors.Add(new WebHttpBehavior { AutomaticFormatSelectionEnabled = true });
        endpoint.Behaviors.Add(new MyVaryAddingInspector());
        host.Open();
        Console.WriteLine("Host opened");

        foreach (string operation in new string[] { "ResponseFormatJson", "ResponseFormatXml", "ContentNegotiated" })
        {
            foreach (string acceptHeader in new string[] { null, "application/json", "text/xml", "text/json" })
            {
                SendGetRequest(baseAddress + "/" + operation, acceptHeader);
            }
        }

        Console.WriteLine("Sending some POST requests with content-nego (but no Vary in response)");
        string jsonBody = "{\"Name\":\"John Doe\",\"Age\":33}";
        SendRequest(baseAddress + "/ContentNegotiatedPost", "POST", "text/json", jsonBody, "text/xml");
        SendRequest(baseAddress + "/ContentNegotiatedPost", "POST", "text/json", jsonBody, "text/json");

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}

So long, it's hard to find the part that actually adds the header. Can it be used to add other response headers, like 'Access-Control-Allow-Origin'

http - WCF REST is not returning a Vary response header when media typ...

wcf http wcf-rest
Rectangle 27 4

Basically you need to perform an HTTP HEAD request for the target URL and check if you got an acceptable response code. Acceptable response code might be OK (200), temporarily moved (???) and other codes that will lead to the page if not right now at least very soon.

Why HEAD? Because GET will download the whole page and HEAD will download only the HTTP header. This will take less time and time is not a friend in this case. The validation should be done very quickly, and making an HTTP request takes time. During those couple seconds (or more, depending on server and network load) the user will wonder what's happening and get frustrated. Unless you can show one of those animated progress indicators to let him know validating its input takes some time.

You should do this like those password strength validators where the value is validated in a background AJAX call once the focus leaves the input control and there's an animated indicator on the side where the result will be shown. In the meantime the user can fill out other information.

The code would something like this:

public class UrlExistenceValidator ... {
    public boolean isValid(Object object) {
        if (!(object instanceof String)) {
            return false;
        }

        final String urlString = (String) object;

        final URL url = new URL(urlString);
        final HttpURLConnection huc =  (HttpURLConnection) url.openConnection();
        huc.setRequestMethod("HEAD");
        huc.connect();

        final int code = huc.getResponseCode();
        return code != 404;
    }
}

java - Play framework URL validator? - Stack Overflow

java validation url playframework-2.0
Rectangle 27 25

Your @Produces annotation is ignored because uncaught exceptions are processed by the jax-rs runtime using a predefined (default) ExceptionMapper If you want to customize the returned message in case of a specific exception you can create your own ExceptionMapper to handle it. In your case you need one to handle the NotFoundException exception and query the "accept" header for the requested type of the response:

@Provider
public class NotFoundExceptionHandler implements ExceptionMapper<NotFoundException>{

    @Context
    private HttpHeaders headers;

    public Response toResponse(NotFoundException ex){
        return Response.status(404).entity(yourMessage).type( getAcceptType()).build();
    }

    private String getAcceptType(){
         List<MediaType> accepts = headers.getAcceptableMediaTypes();
         if (accepts!=null && accepts.size() > 0) {
             //choose one
         }else {
             //return a default one like Application/json
         }
    }
}

I tested it. I continue throwing NotFoundException, but now mapping that exception using ExceptionMapper to setting status code and media type. It works! Before this I tried to return an equivalent response instead throwing NotFoundException, but I have the same result, a text/html 404 response. Is this behaviour due to if my app throws a NotFoundException the default (implicit) ExceptionMapper comes in and override response that I returns to html response? Thanks!

After trying different solution, this is the best and correct solution. It is not obligatory to map NotFoundException. Just use Exception and do what you need

java - How I return HTTP 404 JSON/XML response in JAX-RS (Jersey) on T...

java rest tomcat http-status-code-404 jersey-2.0
Rectangle 27 48

It looks like this issue has to do with the difference between the Content-Type and Accept headers. In HTTP, Content-Type is used in request and response payloads to convey the media type of the current payload. Accept is used in request payloads to say what media types the server may use in the response payload.

So, having a Content-Type in a request without a body (like your GET request) has no meaning. When you do a POST request, you are sending a message body, so the Content-Type does matter.

If a server is not able to process the Content-Type of the request, it will return a 415 HTTP error. (If a server is not able to satisfy any of the media types in the request Accept header, it will return a 406 error.)

In OData v3, the media type "application/json" is interpreted to mean the new JSON format ("JSON light"). If the server does not support reading JSON light, it will throw a 415 error when it sees that the incoming request is JSON light. In your payload, your request body is verbose JSON, not JSON light, so the server should be able to process your request. It just doesn't because it sees the JSON light content type.

You could fix this in one of two ways:

  • Make the Content-Type "application/json;odata=verbose" in your POST request, or

Include the DataServiceVersion header in the request and set it be less than v3. For example:

DataServiceVersion: 2.0;

(Option 2 assumes that you aren't using any v3 features in your request payload.)

Thanks Jen S for the detailed and logical response, it makes perfect sense. I have tried both fixes above and both result in an error 400: Bad Request. I am not sure if this is making progress, could it be a problem now with the format of the json request body I am sending through? I will try and put the response text in the above post.

Yes, it is making progress :). In JSON Verbose request payloads there should not be a "d" outer element. This is for responses only. And I believe you can only post one element at a time, so you shouldn't have an array in the request JSON either. Are you using a library, or crafting these by hand? If you're using a language that has an OData Library, I would suggest using that instead of hand-crafting the payloads. (But not all languages have good libraries at the moment :(.)

That worked! Thanks Jen for all your help. I have posted the final working request and responses above for anyone else who stumbles upon this post. If I had more reputation I would give you an upvote.

Happy that I could help. Glad it's all working now :)

@JenS : hey, could you please look at this (stackoverflow.com/questions/34566007/) question as well. It's on the same lines. Thanks :)

415 Unsupported Media Type - POST json to OData service in lightswitch...

json web-services post odata visual-studio-lightswitch
Rectangle 27 48

It looks like this issue has to do with the difference between the Content-Type and Accept headers. In HTTP, Content-Type is used in request and response payloads to convey the media type of the current payload. Accept is used in request payloads to say what media types the server may use in the response payload.

So, having a Content-Type in a request without a body (like your GET request) has no meaning. When you do a POST request, you are sending a message body, so the Content-Type does matter.

If a server is not able to process the Content-Type of the request, it will return a 415 HTTP error. (If a server is not able to satisfy any of the media types in the request Accept header, it will return a 406 error.)

In OData v3, the media type "application/json" is interpreted to mean the new JSON format ("JSON light"). If the server does not support reading JSON light, it will throw a 415 error when it sees that the incoming request is JSON light. In your payload, your request body is verbose JSON, not JSON light, so the server should be able to process your request. It just doesn't because it sees the JSON light content type.

You could fix this in one of two ways:

  • Make the Content-Type "application/json;odata=verbose" in your POST request, or

Include the DataServiceVersion header in the request and set it be less than v3. For example:

DataServiceVersion: 2.0;

(Option 2 assumes that you aren't using any v3 features in your request payload.)

Thanks Jen S for the detailed and logical response, it makes perfect sense. I have tried both fixes above and both result in an error 400: Bad Request. I am not sure if this is making progress, could it be a problem now with the format of the json request body I am sending through? I will try and put the response text in the above post.

Yes, it is making progress :). In JSON Verbose request payloads there should not be a "d" outer element. This is for responses only. And I believe you can only post one element at a time, so you shouldn't have an array in the request JSON either. Are you using a library, or crafting these by hand? If you're using a language that has an OData Library, I would suggest using that instead of hand-crafting the payloads. (But not all languages have good libraries at the moment :(.)

That worked! Thanks Jen for all your help. I have posted the final working request and responses above for anyone else who stumbles upon this post. If I had more reputation I would give you an upvote.

Happy that I could help. Glad it's all working now :)

@JenS : hey, could you please look at this (stackoverflow.com/questions/34566007/) question as well. It's on the same lines. Thanks :)

415 Unsupported Media Type - POST json to OData service in lightswitch...

json web-services post odata visual-studio-lightswitch
Rectangle 27 3

Accept header is used by HTTP clients to tell the server which type of content they expect/prefer as response. Content-type can be used both by clients and servers to identify the format of the data in their request (client) or response (server) and, therefore, help the other part interpret correctly the information.

I can read in soapui.org/testing-dojo/best-practices/ that content-type is used only for REQUESTS, using methods POST or PUT, so not in the response.. Are they wrong?

I wouldn't say they're wrong, it's only that they are not talking about responses (to be honest I haven't read the full article). SoapUI acts as an HTTP client and the text is written from that perspective. But, if they clearly say, Content-type header only applies to requests, then yes, they are wrong :)

Header parameters: "Accept" and "Content-type" in a REST context - Sta...

rest http-headers
Rectangle 27 5

Although not explicitly mentioned specifically for the 202 - Accepted response code, the Retry-After header seems to be a suitable option. From the documentation:

The Retry-After response-header field can be used [...] to indicate how long the service is expected to be unavailable to the requesting client.

Given that the value is supposed to be "integer number of seconds (in decimal)", if we want a better resolution, would an X-Retry-After header with values in e.g. milliseconds be more appropriate instead?

@JosipRodin I suggest using Retry-After: 0 instead of inventing a custom header because by the time the client gets the response a few milliseconds would have passed anyway and they can retry right away. In the case of an async operation, Retry-After: 0 seems to say "the result isn't ready yet, but feel free to ask again (whenever you wish)."

@Gili but what if I don't want them to ask whenever they wish? For example, if the bulk of the clients are 150ms away, that's 6 requests per second, where I may have had the idea of having only 2 requests per second.

@JosipRodin This header is nothing more than a suggestion to the client. Clients can (and do) ignore it. This header is the server's way of saying: "You can repeat the request sooner if you wish, but I don't think the response will change for the next X seconds". Clients will do what suits them best so you'll never get the level of control you seem to be after.

@Gili that is orthogonal - it still makes sense to be able to communicate reasonable limits, in order to be able to provision resources in a reasonably predictable manner and to be able to better explain to abusive users exactly why they were rate-limited and/or blocked.

rest - HTTP Status 202 - how to provide information about async reques...

rest http-headers http-status-codes