Are Duplicate HTTP Response Headers acceptable? - http-headers

I have not found any specification about whether duplicate HTTP response headers are allowed by the standard, but I need to know if this will cause compatibility issues.
Say I have a response header like this:
HTTP/1.1 302 Moved Temporarily
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.4; JBoss-4.0.3SP1 (build: CVSTag=JBoss_4_0_3_SP1 date=200510231054)/Tomcat-5.5
Cache-Control: no-cache
Cache-Control: no-store
Location: http://localhost:9876/foo.bar
Content-Language: en-US
Content-Length: 0
Date: Mon, 06 Dec 2010 21:18:26 GMT
Notice that there are two Cache-Control headers with different values. Do browsers always treat them as if they are written like "Cache-Control: no-cache, no-store"?

Yes
HTTP RFC2616 available here says:
Multiple message-header fields with the same field-name MAY be present
in a message if and only if the entire field-value for that header
field is defined as a comma-separated list [i.e., #(values)]. It MUST
be possible to combine the multiple header fields into one
"field-name: field-value" pair, without changing the semantics of the
message, by appending each subsequent field-value to the first, each
separated by a comma. The order in which header fields with the same
field-name are received is therefore significant to the interpretation
of the combined field value, and thus a proxy MUST NOT change the
order of these field values when a message is forwarded
So, multiple headers with the same name is ok (www-authenticate is such a case) if the entire field-value is defined as a comma-separated list of values.
Cache-control is documented here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 like this:
Cache-Control = "Cache-Control" ":" 1#cache-directive
The #1cache-directive syntax defines a list of at least one cache-directive elements (see here for the formal definition of #values: Notational Conventions and Generic Grammar)
So, yes,
Cache-Control: no-cache, no-store
is equivalent to (order is important)
Cache-Control: no-cache
Cache-Control: no-store

Note that the HSTS RFC6797 contradicts the RFC2616 (violating the "if and only if" language) by defining the behavior for multiple instances of the STS header, though it is not populated with comma-separated values:
"If a UA receives more than one STS header field in an HTTP
response message over secure transport, then the UA MUST process
only the first such header field."

Related

How are HTTP Cache-Control no-cache field names delimited?

The syntax for the HTTP Cache-Control no-cache directive of a response allows a field-name argument.
RFC7234#5.2.2.2 says:
5.2.2.2. no-cache
Argument syntax:
#field-name
// ...
If the no-cache response directive specifies one or more field-names,
then a cache MAY use the response to satisfy a subsequent request,
subject to any other restrictions on caching.
// ...
The specs state that the no-cache directive may "specif[y] one or more field-names". RFC7230#3.2 defines a field-name as being a token.
What the spec doesn't seem to cover is how multiple field names are delimited/separated.
How are Cache-Control no-cache field names delimited/separated?
Example with no field name (most common usage)
Cache-Control: no-cache
Example with single field name (never personally seen it, technically valid)
Cache-Control: no-cache=foo
Multiple field names ?
Cache-Control: no-cache=foo,bar
Cache-Control: no-cache=foo,bar
Cache-Control: no-cache=foo, bar
Cache-Control: max-age=60, private, no-cache=foo, bar, min-age=30
Cache-Control: max-age=60, private, no-cache="foo, bar", min-age=30
To me, only the last above example (the double-quoted no-cache value) is unambiguous.
What is the correct form to use?
I ask as I need to correctly parse arbitrary Cache-Control header values.
RFC's BNF at RFC2616#14.9 goes:
"no-cache" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1
RFC2616#2.1 explains the # rule is a list:
#rule  
      A construct "#" is defined, similar to "*", for defining lists of  
      elements. The full form is "#element" indicating at least  
       and at most  elements, each separated by one or more commas  
      (",") and OPTIONAL linear white space (LWS). This makes the usual  
      form of lists very easy; a rule such as  
         ( *LWS element *( *LWS "," *LWS element ))  
      can be shown as  
         1#element 
RFC2616#2.2 tells you <"> just means "
<"> = <US-ASCII double-quote mark (34)>
Therefore it would be `Cache-Control: max-age=60, private, no-cache="foo, bar", min-age=30`, as you did in your last one.

Remove Request-Context from Response Header

Somehow in my request response header "Request-Context" coming and i tried to remove that using in web.config and Response.Headers.Remove("Request-Context"); in global.asax but that header is not getting removed.
In the value of that header I am getting some Appid and I am not sure from where that is coming.
Here is response header of my request.
Cache-Control:no-cache, no-store
Content-Encoding:gzip
Content-Length:140
Content-Type:application/json; charset=utf-8
Date:Tue, 20 Feb 2018 09:48:28 GMT
Pragma:no-cache
Request-Context:appId=cid-v1:b650ed48-297a-4ea2-af46-0a5a5d26a82b
Vary:Accept-Encoding
Any help appreciated. Thanks in Advance.
Request-Context is used for cross-component correlation when 2 of your applications use different instrumentation keys.
In this case, knowing caller or callee appId (passed in the header) allows to build application map and trace correlated telemetry across instrumentation keys
You may set RequestTrackingTelemetryModule.SetComponentCorrelationHttpHeaders to false to prevent header to be added to the response.
You can do it in applicationInsights xml file, just find RequestTrackingTelemetryModule element and add false under it.
Refer link: https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/739#issuecomment-367774652

Multipy usage of Cache-Control header

Is it possible to add more than once the Cache-Control header?
What setting will be effective if I see the following headers?
Cache-Control: no-cache, no-store, private
Cache-Control: no-cache
Is setting accumulative?
From RFC 7230, 3.2.2. Field Order:
A recipient MAY combine multiple header fields with the same field
name into one "field-name: field-value" pair, without changing the
semantics of the message, by appending each subsequent field value to
the combined field value in order, separated by a comma.
This request is treated the same as:
Cache-Control: no-cache, no-store, private, no-cache
Note that in RFC 7234, 4.2.1. Calculating Freshness Lifetime:
When there is more than one value present for a given directive
(e.g., two Expires header fields, multiple Cache-Control: max-age
directives), the directive's value is considered invalid.
I believe the example you give is valid but, for example:
Cache-Control: max-age=0
Cache-Control: max-age=3600
would be invalid.

Override default headers for an IXMLHTTPRequest2

I'm trying to send a HTTP request on Windows 8 using an IXMLHTTPRequest2 object and I want to customise the outgoing Accept-Encoding header to something other than the default value of "gzip, deflate". When I try and use SetRequestHeader method to set the Accept-Encoding header, the method call succeeds but the request is still sent with the default header value instead of the value I provided (Verified by using Wireshark to capture the HTTP request).
Sample code (simplified for beverity):
::CoCreateInstance( CLSID_FreeThreadedXMLHTTP60, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &m_pXHR ));
m_pXHR->Open( "GET", "http://192.168.0.100/test", m_pXHRCallback.Get(), NULL, NULL, NULL,NULL );
m_pXHR->SetRequestHeader( L"Accept-Encoding", L"gzip" );
m_pXHR->Send( NULL, 0 );
Wireshark capture of request that gets made:
GET /users/me/id HTTP/1.1
Accept: */*
Host: 192.168.0.100
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
According to the docs for SetRequestHeader, it is an append operation only. You're getting the gzip Accept-Encoding, so I think it's working as intended. I don't see a way of removing the default header, however.
It seems that you can use IXMLHTTPRequest2::SetProperty() with XHR_PROP_NO_DEFAULT_HEADERS to suppress the default headers.
See: http://msdn.microsoft.com/en-us/library/windows/desktop/hh831167(v=vs.85).aspx
It seems that the IXMLHTTPRequest2 API is plainly broken, as it doesn't have a way to remove a header. Or, perhaps, documentation is broken because it doesn't mention that passing an empty string or NULL removes a header.
Also, according to IXMLHTTPRequest2::SetRequestHeader declaration:
virtual HRESULT STDMETHODCALLTYPE SetRequestHeader(
/* [ref][string][in] */ __RPC__in_string const WCHAR *pwszHeader,
/* [unique][string][in] */ __RPC__in_opt_string const WCHAR *pwszValue) = 0;
header's value is marked as optional (__RPC__in_opt_string) and can be NULL.
So, if you really want to set a header's value, the only proper way that works with IXMLHTTPRequest2 is to do this:
m_pXHR->SetRequestHeader(L"SomeMyHeader", L"");
m_pXHR->SetRequestHeader(L"SomeMyHeader", L"value");
This way you can remove, or change some default headers:
m_pXHR->SetRequestHeader(L"Accept-Language", L"");
Since this isn't documented, this may or may not work for you at some point on some particular version of Windows. If you tried to use IXMLHTTPRequest2 heavily you'd come to the same conclusion as me: it's just broken crap. This for example doesn't work:
m_pXHR->SetRequestHeader(L"Accept-Encoding", L"");
Seems that some dude who implemented IXMLHTTPRequest2 put lots of undocumented logic in there:
You can complete remove some headers if you set them to NULL or an empty string (for example, Accept-Language header, or your own headers can be removed).
You can change, but not remove some headers (for example, User-Agent header).
You cannot change some headers at all (for example, Accept-Encoding header).
When you call ->Send on IXMLHTTPRequest2, internally they unconditionally set Accept-Encoding to whatever they feel like using. That means that you cannot add some alternative encoding like brotli without resorting to hacks and custom headers.
They should just start using libcurl and expose its API instead of exposing IXMLHTTPRequest2 shameful quality.

getting directly only the contents after the first nth character in vb.net

Is there any way we could get directly say the 1000 characters after the first 5000 characters, skipping everything before that after sending in an HTTP request to an HTTPS page using either GET or POST in VB.NET?
The reason why I ask this question is because in one of the webpage I am trying the get through my program, the website is sending response data in chunks with the first chunk containing some javascript garbage that I have no interest in, the only data I care is in the second chunk and
I have no idea how to get the second chunk after receiving the first one since it is within the same HTTP request
It would save some time and Internet traffic if I can skip the first chunk that I do not need.
Is that possible or I am just day dreaming?
Many thanks!
ADDED:
Here is how a typical header of the response I am getting from the webpage I am trying to get:
Date: Mon, 20 Jun 2011 13:21:56 GMT
Set-Cookie: JSESSIONID=1AF1AF9EF936E1CB2FA85B750EDC67C4; Path=****some path******; Secure
Content-Type: text/html; charset=ISO-8859-1
Transfer-Encoding: chunked
Set-Cookie: **********some cookie***************
path=/
Vary: Accept-Encoding, User-Agent
Not sure if that helps, but as you can see, the chunk size is not visible to me, there is no "Trailer" in the header as well.
Fun little problem. Look at RANGE in the following GET request.
GET /file.txt HTTP/1.1
Host: localhost
Range: bytes=5000-6000
Connection: Close
Edit: Found a HTTP example.
Here is an example in PHP. (Sorry I couldn't find any VB.NET examples).