API - Other

[C#] Fixing Duplicate API Requests by Idempotency-Key

ASP.NET Core

First, ensure that MemoryCache is available by adding it to your project. In Startup.cs or Program.cs, configure memory cache.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMemoryCache(); // Register Memory Cache
    services.AddControllers();
}


This middleware will check if an incoming request has an Idempotency-Key and ensure that duplicate requests with the same key are rejected.

public class IdempotencyMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMemoryCache _cache;


    public IdempotencyMiddleware(RequestDelegate next, IMemoryCache cache)
    {
        _next = next;
        _cache = cache;
    }


    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue("Idempotency-Key", out var idempotencyKey))
        {
            context.Response.StatusCode = 400; // Bad Request
            await context.Response.WriteAsync("Idempotency-Key is required.");
            return;
        }


        // Check if the key exists in memory
        if (_cache.TryGetValue(idempotencyKey, out _))
        {
            context.Response.StatusCode = 409; // Conflict
            await context.Response.WriteAsync("Duplicate request.");
            return;
        }


        // Store the key in cache to prevent duplicate processing
        _cache.Set(idempotencyKey, true, TimeSpan.FromMinutes(10)); // Cache for 10 minutes


        // Proceed to the next middleware or controller
        await _next(context);
    }
}


In Startup.cs or Program.cs, register the middleware in the request pipeline.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<IdempotencyMiddleware>(); // Add the middleware to the pipeline


    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}


Here’s a sample API controller that can use this Idempotency middleware.

[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
    [HttpPost]
    public IActionResult CreateOrder([FromBody] OrderRequest orderRequest)
    {
        // Simulate order creation logic
        return Ok(new { Message = "Order created successfully." });
    }
}


public class OrderRequest
{
    public string ProductId { get; set; }
    public int Quantity { get; set; }
}


Explanation:

  1. Middleware: The IdempotencyMiddleware checks for an Idempotency-Key in the request headers. If it’s missing or duplicated, the request is rejected with an appropriate HTTP status code.
  2. Cache: The key is stored in MemoryCache for a short period (e.g., 10 minutes). This prevents duplicate requests within that time window.
  3. Flexibility: You can adjust the expiration time (TimeSpan.FromMinutes(10)) based on how long you want to keep requests idempotent.


ASP.NET Framework

In an ASP.NET Framework project, you can use MemoryCache from System.Runtime.Caching. You’ll need to add this in your Global.asax.cs file for configuration.

using System;
using System.Runtime.Caching;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;


namespace YourAppNamespace
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static ObjectCache Cache = MemoryCache.Default;


        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
    }
}


In ASP.NET Framework, you can use Action Filters to implement the Idempotency mechanism.

using System;
using System.Runtime.Caching;
using System.Web.Mvc;


namespace YourAppNamespace.Filters
{
    public class IdempotencyFilter : ActionFilterAttribute
    {
        private readonly ObjectCache _cache;


        public IdempotencyFilter()
        {
            _cache = MemoryCache.Default;
        }


        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var request = filterContext.HttpContext.Request;
            var response = filterContext.HttpContext.Response;


            // Check for Idempotency-Key in the headers
            var idempotencyKey = request.Headers["Idempotency-Key"];
            if (string.IsNullOrEmpty(idempotencyKey))
            {
                response.StatusCode = 400; // Bad Request
                filterContext.Result = new ContentResult { Content = "Idempotency-Key is required." };
                return;
            }


            // Check if the key exists in cache
            if (_cache.Contains(idempotencyKey))
            {
                response.StatusCode = 409; // Conflict
                filterContext.Result = new ContentResult { Content = "Duplicate request." };
                return;
            }


            // Store the key in cache to prevent duplicate processing
            _cache.Add(idempotencyKey, true, DateTimeOffset.UtcNow.AddMinutes(10)); // Cache for 10 minutes
        }
    }
}


Now, you can apply the IdempotencyFilter to your API controller or action method.

using System.Web.Mvc;
using YourAppNamespace.Filters;


namespace YourAppNamespace.Controllers
{
    public class OrdersController : Controller
    {
        // Apply IdempotencyFilter at the action level
        [HttpPost]
        [IdempotencyFilter]
        public ActionResult CreateOrder(OrderRequest orderRequest)
        {
            // Simulate order creation logic
            return Json(new { Message = "Order created successfully." });
        }
    }


    public class OrderRequest
    {
        public string ProductId { get; set; }
        public int Quantity { get; set; }
    }
}


You can also register this filter globally in FilterConfig.cs if you want it applied to all your controllers.

using System.Web.Mvc;
using YourAppNamespace.Filters;


public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new IdempotencyFilter());
    }
}


Explanation:

  1. MemoryCache: We use MemoryCache from System.Runtime.Caching to store the Idempotency-Key for 10 minutes, preventing duplicate calls within that period.
  2. Idempotency Filter: The IdempotencyFilter checks the request headers for an Idempotency-Key, ensures the request is not duplicated, and stores the key in the cache.
  3. Controller: The controller action (CreateOrder) uses the IdempotencyFilter to ensure that duplicate calls with the same key are blocked.

[C#] Limit API key usage

using Throttle;

var throttlePolicy = new ThrottlePolicy(perSecond: 10, perMinute: 100, perHour: 1000);
var throttleFilter = new ThrottlingFilter(throttlePolicy);

config.Filters.Add(throttleFilter);

[C#] Validate the X-API-KEY

After adding the X-API-KEY to the request, we need to validate it to ensure that the API key is correct and has the necessary permissions to access the requested resource. This can be done using middleware in our API. Here’s an example of how to validate the X-API-KEY using middleware in C#:

using Microsoft.AspNetCore.Http;

public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;

    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue("X-API-KEY", out var apiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("API key missing");
            return;
        }

        if (apiKey != "YOUR_API_KEY")
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("Invalid API key");
            return;
        }

        await _next(context);
    }
}


Configuring the middleware


To implement the above middleware for securing C# APIs with X-API-KEY, there are a few configurations that need to be made in our ASP.NET Core application:

public class ApiKeyValidator : IApiKeyValidator
{
    private readonly IConfiguration _configuration;

    public ApiKeyValidator(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public bool Validate(string apiKey)
    {
        // Retrieve the expected API key from the app settings
        var expectedApiKey = _configuration.GetValue<string>("ApiKeys:MyApiKey");

        // Compare the provided API key with the expected API key
        return apiKey == expectedApiKey;
    }
}


public interface IApiKeyValidator
{
    bool Validate(string apiKey);
}


In .Net Core:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add the ApiKeyValidator as a singleton
        services.AddSingleton<IApiKeyValidator, ApiKeyValidator>();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // Add the ApiKeyMiddleware to the middleware pipeline
        app.UseMiddleware<ApiKeyMiddleware>();

        // Add any additional middleware here, such as authentication middleware
    }
}


In .Net 5, 6:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<IApiKeyValidator, MyApiKeyValidator>();

// Add the API key middleware to the pipeline
builder.Use(async (context, next) =>
{
    // Get the API key from the X-API-KEY header
    var apiKey = context.Request.Headers["X-API-KEY"];

    // Validate the API key using the IApiKeyValidator service
    var apiKeyValidator = context.RequestServices.GetRequiredService<IApiKeyValidator>();
    if (!apiKeyValidator.Validate(apiKey))
    {
        // If the API key is invalid, return a 401 Unauthorized response
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return;
    }

    // If the API key is valid, pass the request to the next middleware in the pipeline
    await next.Invoke();
});

builder.MapGet("/hello", (HttpContext context) =>
{
    // If the API key is valid, return a 200 OK response with a "Hello, world!" message
    context.Response.StatusCode = StatusCodes.Status200OK;
    return context.Response.WriteAsync("Hello, world!");
});

var app = builder.Build();

app.Run();


Creating the Attribute


We can create an ApiKeyAttribute that we can use to decorate our controllers and actions in C#:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

public class ApiKeyAttribute : ActionFilterAttribute
{
    private readonly IApiKeyValidator _apiKeyValidator;

    public ApiKeyAttribute(IApiKeyValidator apiKeyValidator)
    {
        _apiKeyValidator = apiKeyValidator;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Get the API key from the X-API-KEY header
        var apiKey = context.HttpContext.Request.Headers["X-API-KEY"];

        // Validate the API key using the IApiKeyValidator service
        if (!_apiKeyValidator.Validate(apiKey))
        {
            // If the API key is invalid, set the response status code to 401 Unauthorized
            context.Result = new UnauthorizedResult();
            return;
        }

        // If the API key is valid, continue with the action execution
        base.OnActionExecuting(context);
    }
}


[ApiController]
[Route("api/[controller]")]
[ApiKey] // decorate the controller with the ApiKeyAttribute
public class MyController : ControllerBase
{
    [HttpGet]
    [ApiKey] // decorate the action with the ApiKeyAttribute
    public IActionResult Get()
    {
        return Ok("Hello, world!");
    }
}

API Status Code Guide

Informational Responses

  • 100 - Continue: The server has received the request headers, and the client should proceed to send the request body.
  • 101 - Switching Protocols: The requester has asked the server to switch protocols, and the server has agreed to do so.
  • 102 - Processing: The server has received and is processing the request, but no response is available yet.
  • 103 - Early Hints: The server is likely to send a final response with the headers provided, allowing the client to start preloading resources.


Success

  • 200 - OK: Success! Everything worked as expected.
  • 201 - Created: Great! Your item has been successfully created.
  • 202 - Accepted: The request has been accepted for processing, but the processing is not yet complete.
  • 203 - Non-Authoritative Information: The server successfully processed the request, but the response comes from a copy or modified version of the original resource.
  • 204 - No Content: The server successfully processed the request, but there is no content to return.
  • 205 - Reset Content: Reset Content: Tells the client to reset the document view (e.g., form inputs) as the response does not include new content.
  • 206 - Partial Content: The server is delivering only part of the resource due to a range header sent by the client.
  • 207 - Multi-Status: Indicates multiple statuses for various operations in a Web Distributed Authoring and Versioning (WebDAV) request, often used with XML.
  • 208 - Already Reported: Used inside a DAV:propstat response to avoid repeatedly enumerating the internal members of multiple bindings to the same collection.
  • 226 - IM Used (HTTP Delta Encoding): The server has fulfilled the request for the resource, and the response represents the result of one or more instance-manipulations applied to the current instance.


Redirection

  • 300 - Multiple Choices: There are multiple options that the client may follow.
  • 301 - Moved Permanently: The requested resource has been moved to a new URL permanently.
  • 302 - Found: Redirects the client to a different URL temporarily; commonly used for redirecting web browsers.
  • 303 - See Other: Directs the client to retrieve the requested resource at a different URI using a GET method.
  • 304 - Not Modified: The content has not been modified since the last request. The client can continue to use the cached version.
  • 305 - Use Proxy: Specifies a proxy server for the requested resource. (Not widely used due to security issues).
  • 306 - Unused: Originally intended as a "Switch Proxy" response code but is no longer used.
  • 307 - Temporary Redirect: The requested resource temporarily resides under a different URL, but future requests should still use the original URL.
  • 308 - Permanent Redirect: The resource has been permanently moved to a new URL, and future requests should use the new URL.


Client Errors

  • 400 - Bad Request: The request cannot be fulfilled due to bad syntax.
  • 401 - Unauthorized: It appears that the password and/or username you entered was incorrect.
  • 402 - Payment Required: Reserved for future use to indicate payment is required before accessing the requested resource (often seen in subscription-based services).
  • 403 - Forbidden: Sorry, employees and staff only.
  • 404 - Not Found: We're sorry, but the page you're looking for is missing, hiding, or maybe it moved somewhere else and forgot to tell you.
  • 405 - Method Not Allowed: The method specified in the Request-Line is not allowed for the specified resource.
  • 406 - Not Acceptable: The server cannot provide a response matching the Accept headers in the request, indicating the client should modify its request.
  • 407 - Proxy Authentication Required: The client must authenticate itself with the proxy before the request can be processed.
  • 408 - Request Timeout: Your browser failed to send a request in the time allowed by the server.
  • 409 - Conflict: The request could not be completed due to a conflict with the current state of the resource.
  • 410 - Gone: The requested resource is no longer available on the server and no forwarding address is provided, indicating permanent unavailability.
  • 411 - Length Required: The server requires a valid Content-Length header for the request to be fulfilled.
  • 412 - Precondition Failed: One or more conditions in the request headers were not met, so the server refuses to process it.
  • 413 - Payload Too Large: The request payload is too large for the server to process, prompting the client to reduce the payload size.
  • 414 - URI Too Long: The URL you entered is longer than the maximum length allowed by the server.
  • 415 - Unsupported Media Type: The server does not support the media format of the request payload, so it cannot be processed.
  • 416 - Range Not Satisfiable: The server cannot fulfill the range specified by the client, often seen in range requests for downloading files.
  • 417 - Exception Failed: The server cannot meet the requirements in the Expect request header.
  • 418 - I'm a teapot: An April Fool’s joke code from the Hyper Text Coffee Pot Control Protocol (HTCPCP) indicating the server refuses to brew coffee because it's a teapot.
  • 421 - Misdirected Request: The request was directed at a server that is not able to produce a response (e.g., for server misconfiguration or load balancing issues).
  • 422 - Unprocessable Entity: The request was well-formed but couldn't be processed due to validation errors. Please check your input.
  • 423 - Locked: The requested resource is currently locked (often in WebDAV when a file or resource is in use by another process).
  • 424 - Failed Dependency: The request failed because it depended on another request that also failed (typically used in WebDAV).
  • 425 - Too Early: The server is not willing to risk processing a request that might be replayed (to avoid premature replay attacks).
  • 426 - Upgrade Required: The client should switch to a different protocol as specified in the Upgrade header (often seen in cases requiring HTTPS instead of HTTP).
  • 428 - Precondition Required: The server requires the request to be conditional to prevent unintended overwrites or modifications (e.g., ensuring If-Match headers are used).
  • 429 - Too Many Requests: The user has sent too many requests in a given amount of time, triggering rate-limiting mechanisms.
  • 431 - Request Header Fields Too Large: The server refuses to process the request due to excessively large header fields.
  • 451 - Unavailable for Legal Reasons: The server cannot process the request due to legal restrictions on content (e.g., censorship laws).
  • 499 - Client Closed Request: The client closed the connection before the server could send a response (common in Nginx to indicate a client timeout).


Server Errors

  • 500 - Internal Server Error: The request was unsuccessful due to an unexpected condition encountered by the server.
  • 501 - Not Implemented: The server does not support the functionality required to fulfill the request.
  • 502 - Bad Gateway: The server received an invalid response from the upstream server while trying to fulfill the request.
  • 503 - Service Unavailable: The server is currently unable to handle the request due to temporary overloading or maintenance.
  • 504 - Gateway Timeout: The upstream server failed to send a request in the time allowed by the server.
  • 505 - HTTP Version Not Supported: The server does not support the HTTP version specified in the request.
  • 507 - Insufficient Storage: The server cannot store the representation needed to complete the request (common in WebDAV when storage space is full).
  • 508 - Loop Detected: The server detected an infinite loop while processing the request (common in WebDAV for cyclic resource references).
  • 510 - Not Extended: The server requires further extensions to fulfill the request, often needing additional specifications.
  • 511 - Network Authentication Required: The client needs to authenticate to access the network, typically used for captive portals in public Wi-Fi.
  • 599 - Network Connect Timeout Error: Indicates a network connection timeout at the network level, often used in unofficial custom server logs.

CONNECT Method

The CONNECT method is for making end-to-end connections between a client and a server. It makes a two-way connection like a tunnel between them. For example, we can use this method to safely transfer a large file between the client and the server.

Content-Security-Policy

The HTTP Content-Security-Policy response header allows web site administrators to control resources the user agent is allowed to load for a given page. With a few exceptions, policies mostly involve specifying server origins and script endpoints. This helps guard against cross-site scripting attacks (Cross-site_scripting).


Syntax

Content-Security-Policy: <policy-directive>; <policy-directive>

where <policy-directive> consists of: <directive> <value> with no internal punctuation.


Directives

Fetch directives

  • child-src - Defines the valid sources for web workers and nested browsing contexts loaded using elements such as <frame> and <iframe>.
  • connect-src - Restricts the URLs which can be loaded using script interfaces.
  • default-src - Serves as a fallback for the other fetch directives.
  • font-src - Specifies valid sources for fonts loaded using @font-face.
  • frame-src - Specifies valid sources for nested browsing contexts loading using elements such as <frame> and <iframe>.
  • img-src - Specifies valid sources of images and favicons.
  • manifest-src - Specifies valid sources of application manifest files.
  • media-src - Specifies valid sources for loading media using the <audio>, <video> and <track> elements.
  • object-src - Specifies valid sources for the <object>, <embed>, and <applet> elements.
  • prefetch-src - Specifies valid sources to be prefetched or prerendered.
  • script-src - Specifies valid sources for JavaScript and WebAssembly resources.
  • script-src-elem - Specifies valid sources for JavaScript <script> elements.
  • script-src-attr - Specifies valid sources for JavaScript inline event handlers.
  • style-src - Specifies valid sources for stylesheets.
  • style-src-elem - Specifies valid sources for stylesheets <style> elements and <link> elements with rel="stylesheet".
  • style-src-attr - Specifies valid sources for inline styles applied to individual DOM elements.
  • worker-src - Specifies valid sources for Worker, SharedWorker, or ServiceWorker scripts.


Document directives

  • base-uri - Restricts the URLs which can be used in a document's <base> element.
  • sandbox - Enables a sandbox for the requested resource similar to the <iframe> sandbox attribute.


Navigation directives

  • form-action - Restricts the URLs which can be used as the target of a form submissions from a given context.
  • frame-ancestors - Specifies valid parents that may embed a page using <frame>, <iframe>, <object>, <embed>, or <applet>.
  • navigate-to - Restricts the URLs to which a document can initiate navigation by any means, including <form> (if form-action is not specified), <a>, window.location, window.open, etc.


Reporting directives

  • report-uri - Instructs the user agent to report attempts to violate the Content Security Policy. These violation reports consist of JSON documents sent via an HTTP POST request to the specified URI.
  • report-to - Fires a SecurityPolicyViolationEvent.


Other directives

  • require-sri-for - Requires the use of SRI for scripts or styles on the page.
  • require-trusted-types-for - Enforces Trusted Types at the DOM XSS injection sinks.
  • trusted-types - Used to specify an allow-list of Trusted Types policies. Trusted Types allows applications to lock down DOM XSS injection sinks to only accept non-spoofable, typed values in place of strings.
  • upgrade-insecure-requests - Instructs user agents to treat all of a site's insecure URLs (those served over HTTP) as though they have been replaced with secure URLs (those served over HTTPS). This directive is intended for websites with large numbers of insecure legacy URLs that need to be rewritten.


Deprecated directives

  • block-all-mixed-content - Prevents loading any assets using HTTP when the page is loaded using HTTPS.
  • plugin-types - Restricts the set of plugins that can be embedded into a document by limiting the types of resources which can be loaded.
  • referrer - Used to specify information in the Referrer (sic) header for links away from a page. Use the Referrer-Policy header instead.


Values

Keyword values

  • none - Won't allow loading of any resources.
  • self - Only allow resources from the current origin.
  • strict-dynamic - The trust granted to a script in the page due to an accompanying nonce or hash is extended to the scripts it loads.
  • report-sample - Require a sample of the violating code to be included in the violation report.


Unsafe keyword values

  • unsafe-inline - Allow use of inline resources.
  • unsafe-eval - Allow use of dynamic code evaluation such as eval, setImmediate, and window.execScript.
  • unsafe-hashes - Allows enabling specific inline event handlers.


Hosts values

  • Host - Only allow loading of resources from a specific host, with optional scheme, port, and path. e.g. example.com, *.example.com, https://*.example.com:12/path/to/file.js. | Path parts in the CSP that end in / match any path they are a prefix of. e.g. example.com/api/ will match URLs like example.com/api/users/new. | Other path parts in the CSP are matched exactly e.g. example.com/file.js will match http://example.com/file.js and https://example.com/file.js, but not https://example.com/file.js/file2.js.
  • Scheme - Only allow loading of resources over a specific scheme, should always end with :. e.g. https:, http:, data: etc.


Other values

  • nonce-* - A cryptographic nonce (only used once) to allow scripts. The server must generate a unique nonce value each time it transmits a policy. It is critical to provide a nonce that cannot be guessed as bypassing a resource's policy is otherwise trivial. This is used in conjunction with the script tag nonce attribute. e.g. nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV
  • sha*-* - sha256, sha384, or sha512. followed by a dash and then the sha* value. e.g. sha256-jzgBGA4UWFFmpOBq0JpdsySukE1FrEN5bUpoK8Z29fY=


Example

Using the HTTP header

Content-Security-Policy: default-src https:


Using the HTML meta element

<meta http-equiv="Content-Security-Policy" content="default-src https:" />

DELETE Method

As the name suggests, the DELETE method deletes a resource. The DELETE method is idempotent; regardless of the number of calls, it returns the same result.


Deletes customer by Customer ID

/api/customers/123

GET Method

If we want to retrieve data from a resource like websites, servers or APls, we send them a GET Request. For example, we send a GET request to the server if we want a list of our customers or a specific customer.


Returns a customer by Customer ID

/api/customers/{customer- id}


Returns all customers

/api/customers



HEAD Method

The HEAD method is similar to the GET method. But it doesn't have any response body, so if it mistakenly returns the response body, it must be ignored.

Headers in HTTP Requests

Host

The Host request header specifies the host and port number of the server to which the request is being sent. If no port is included, the default port for the service requested is implied (e.g., 443 for an HTTPS URL, and 80 for an HTTP URL).


Host: medium.com


User-Agent

The User-Agent request header is a characteristic string that lets servers identify the application, operating system, vendor, and/or version of the requesting client.


User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36


Using the User-Agent header, web-servers can collect general information about the requesting client and serve them accordingly.


Accept-Language

The Accept-Language header conveys the default language settings for a user. If a web-server supports different language versions for a web-page, it can redirect the client based on this header.


Accept-Language:en-GB,en-US;q=0.9,en;q=0.8


It can carry multiple languages, separated by commas. The first one is the preferred language, and each other listed language can carry a q value, which is an estimate of the user's preference for the language on a scale of 0 to 1.


Accept-Encoding

The Accept-Encoding header indicates the content encoding (usually a compression algorithm) that the client can understand.


Accept-Encoding: gzip, deflate, br, zstd


Most modern browsers support gzip and will send this in the header. The web server then can send the HTML output in a compressed format. This can reduce the size by up to 80% to save bandwidth and time.


If-Modified-Since

The If-Modified-Since request HTTP header makes the request conditional: the server sends back the requested resource, with a 200 status, only if it has been last modified after the given date. If the resource has not been modified since, the response is a 304 without any body.


If-Modified-Since: Sat, 28 Sep 2024 03:21:52 GMT


Cookie

The Cookie header sends the cookies stored in your browser for that domain.


Cookie: PHPSESSID=298zf09hf012fh2; csrftoken=u32t4o3tb3gg43; _gat=1


These are name=value pairs separated by semicolons. Cookies can also contain the session id.


Referer

The Referer header allows a server to identify referring pages that people are visiting from or where requested resources are being used. This data can be used for analytics, logging, optimised caching, and more.


Referer: <url>


Authorization

The HTTP Authorization request header can be used to provide credentials that authenticate a client with a server, allowing access to protected resources.


When a web page asks for authorization, the browser opens a login window. When you enter a username and password in this window, the browser sends another HTTP request, but this time it contains this header.


// Bearer 
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

// Basic
Authorization: Basic base64(username:password)

// API Key
Authorization: ApiKey your-api-key

Headers in HTTP Response

Cache Control

The Cache-Control HTTP header controls the browser caching behaviour. When someone visits a website, their browser will save certain resources, such as images and website data, in a store called the cache. When that user revisits the same website, cache-control sets the rules which determine whether that user will have those resources loaded from their local cache, or whether the browser will have to send a request to the server for fresh resources.


Cache-Control: max-age=3600, public


Caching can also be prevented by using the no-cache directive.


Cache-Control: no-cache


Content Type

The Content-Type header is used to indicate the media type of the responded payload. For example, if the HTTP response contains an HTML file, the Content-Type header will have the following value.


Content-Type: text/html; charset=UTF-8


Browser uses the Content-Type header to decide how to interpret the payload data.


Content Disposition

The Content-Disposition header is important for controlling how browser handles file downloads initiated by a web-server. It provides information about the file being downloaded, influencing whether the browser displays it inline or offers it as a download.


Content-Disposition: attachment; filename="download.zip"


A value of inline for Content-Disposition will instruct the browser to display the file inside the browser instead of downloading it.


Content-Length

The HTTP Content-Length header indicates the size, in bytes, of the message body sent to the recipient.


Content-Length: 89123


This is especially useful for file downloads. That's how the browser can determine the progress of the download.


Location

The Location header is used during re-directions. When the server responds with a 301 or 302 status, the browser will consult the Location header to decide the re-direction.


Location: /index.html


Set-Cookie

When a web-server wants to store certain data on the browser, it sends an HTTP request with Set-Cookie header included. This small amount of data is called cookie and is kept in browser's storage. All the subsequent requests to the web-server will then contain these cookies in header.


Set-Cookie: sessionId=38afes7a8


If the expiration date is not specified, the cookie is deleted when the browser window is closed.

HTTP Methods

The Hypertext Transfer Protocol (HTTP) is designed to enable communications between clients and servers.


The protocol works by clients sending requests to the servers and servers responding to the requests. We do CRUD operations (Create, Read, Update, Delete) by sending HTTP requests with different HTTP methods, sometimes called HTTP verbs. GET and POST are the most frequently used HTTP methods.