Grpc-message: Policy checks are unavailable - grpc

my firebase-admin client gets this message in HTTP2 header: "grpc-message" = "Policy checks are unavailable." and "grpc-status" = "14". client doesn't get any DATA payload in response. Does anybody have any idea about in what situation grpc will return this error message?
Specifically, I'm coding golang app on go/http2 to send a firebase-admin request to query my data on firebase. Here is the data flow of HTTP2. I expect to get DATA frame between the last two HEADERS frames as response but I didn't get it.
Also I checked this link grpc.github.io/grpc/core/md_doc_statuscodes.html and didn't find the grpc-message I got.
I used firebase-admin js client to query my data and it's working fine. So I don't think this is service api issue.
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: wrote SETTINGS len=12, settings: ENABLE_PUSH=0, INITIAL_WINDOW_SIZE=4194304
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: wrote WINDOW_UPDATE len=4 (conn) incr=1073741824
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: read SETTINGS len=18, settings: MAX_CONCURRENT_STREAMS=100, INITIAL_WINDOW_SIZE=1048576, MAX_HEADER_LIST_SIZE=65536
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: wrote SETTINGS flags=ACK len=0
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: read WINDOW_UPDATE len=4 (conn) incr=983041
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: read SETTINGS flags=ACK len=0
2022/01/25 14:42:22 http2: Transport encoding header ":authority" = "firestore.googleapis.com:443"
2022/01/25 14:42:22 http2: Transport encoding header ":method" = "POST"
2022/01/25 14:42:22 http2: Transport encoding header ":path" = "/google.firestore.v1.Firestore/RunQuery"
2022/01/25 14:42:22 http2: Transport encoding header ":scheme" = "https"
2022/01/25 14:42:22 http2: Transport encoding header "x-goog-request-params" = "parent=projects%2Flijie-dependencies-test%2Fdatabases%2F(default)%2Fdocuments"
2022/01/25 14:42:22 http2: Transport encoding header "accept-encoding" = "identity"
2022/01/25 14:42:22 http2: Transport encoding header "user-agent" = "grpc-node-js/1.4.4"
2022/01/25 14:42:22 http2: Transport encoding header "te" = "trailers"
2022/01/25 14:42:22 http2: Transport encoding header "grpc-accept-encoding" = "identity,deflate,gzip"
2022/01/25 14:42:22 http2: Transport encoding header "content-type" = "application/grpc"
2022/01/25 14:42:22 http2: Transport encoding header "x-goog-api-client" = "gax/2.28.1 gapic/4.15.1 gl-node/10.18.1 grpc/1.4.4 gccl/4.15.1 fire/10.0.0"
2022/01/25 14:42:22 http2: Transport encoding header "google-cloud-resource-prefix" = "projects/lijie-dependencies-test/databases/(default)"
2022/01/25 14:42:22 http2: Transport encoding header "authorization" = "Bearer [[REDACTED]]"
2022/01/25 14:42:22 http2: Transport encoding header "grpc-timeout" = "299901m"
2022/01/25 14:42:22 http2: Transport encoding header "accept-encoding" = "gzip"
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: wrote HEADERS flags=END_HEADERS stream=3 len=925
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: wrote DATA stream=3 len=80 data="\x00\x00\x00\x00K\n>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\t\x12\a\x12\x05users"
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: wrote DATA flags=END_STREAM stream=3 len=0 data=""
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: read HEADERS flags=END_HEADERS stream=3 len=176
2022/01/25 14:42:22 http2: decoded hpack field header field ":status" = "200"
2022/01/25 14:42:22 http2: decoded hpack field header field "content-type" = "application/grpc"
2022/01/25 14:42:22 http2: decoded hpack field header field "date" = "Tue, 25 Jan 2022 20:42:22 GMT"
2022/01/25 14:42:22 http2: decoded hpack field header field "alt-svc" = "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
2022/01/25 14:42:22 http2: Framer 0xc00e8629a0: read HEADERS flags=END_STREAM|END_HEADERS stream=3 len=47
2022/01/25 14:42:22 http2: decoded hpack field header field "grpc-status" = "14"
2022/01/25 14:42:22 http2: decoded hpack field header field "grpc-message" = "Policy checks are unavailable."

Related

What a connect message header should look like in http2?

I found that a get message header looks like:
:method: GET
:scheme: https
:authority: server.net
:path: /config
accept: */*
accept-encoding: gzip,deflate
What a connect message header should look like?
This example is from the RFC of http2:
GET /resource HTTP/1.1 HEADERS
Host: example.org ==> + END_STREAM
Accept: image/jpeg + END_HEADERS
:method = GET
:scheme = https
:path = /resource
host = example.org
accept = image/jpeg
I want to know the equivalent of the connect header in http2.
In Http1 is:
CONNECT example.org:443 HTTP/1.1
Host: example.org:443
The format of the CONNECT method in HTTP/2 is specified in section 8.3.
With the formatting you used above looks like:
:method: CONNECT
:authority: proxy.net:8080
As specified, :scheme and :path must be omitted.
The HTTP/2 CONNECT method can also be used for bootstrapping other protocols (see for example WebSocket over HTTP/2), so that, additionally, the :protocol pseudo-header may also be present.
Remember however that this is only a textual representation of HTTP/2; the bytes that actually travel over the network are different since you must encode them using HPACK.
Unless you are actually writing an HTTP/2 implementation, it is better that you use existing libraries (available in virtually any programming language) to send HTTP/2 requests (of any kind): the libraries will take care of converting your CONNECT request into the proper bytes to send over the network.

Lua HTTP Request TCP messages

I am sending HTTP requests using socket.http to a Shelly 2.5 relay IOT device that contains a Mongoose/6.18 server running on an ESP8266, but am having problems.
HTTP requests to this device work as expected when initiated from postman or browser: the device's server responds as expected.
However if I send requests using Lua 5.3 socket.http module, the server does NOT respond. I've used tcpdump to see what's going on and from what I see, unlike browsers or postman which send the HTTP request in one TCP message containing both the HTTP startline and headers, Lua seems to send two separate TCP messages, first for the startline only, then a second for the headers. Mongoose responds with an ack when the startline is sent, then Lua sends the headers and Mongoose does not respond. Lua then tries 5 times to resend the headers before giving up.
I don't normally have problems using socket.http when sending HTTP requests to other servers.
I'm not sure if the 2-part HTTP message is what is causing the issue with this particular device, or if I'm perhaps misinterpreting the tcpdump output:
18:24:23.823886 IP 192.168.1.140.41894 > 192.168.1.136.http: Flags [P.], seq 1:151, ack 1, win 65392, length 150: HTTP: GET /settings/actions?index=0&name=out_on_url&enabled=true&urls[]=http://192.168.1.107:6667/b6cb7ffc-7919-41e6-ab80-6bed8b117753/relay/0/on HTTP/1.1
E.....#.#.6............Pj.n.....P..p....GET /settings/actions?index=0&name=out_on_url&enabled=true&urls[]=http://192.168.1.107:6667/b6cb7ffc-7919-41e6-ab80-6bed8b117753/relay/0/on HTTP/1.1
18:24:23.898872 IP 192.168.1.136.http > 192.168.1.140.41894: Flags [.], ack 151, win 2770, length 0
E..(.6#...v5.........P......j.o:P.
.......5...
18:24:23.898946 IP 192.168.1.140.41894 > 192.168.1.136.http: Flags [P.], seq 151:447, ack 1, win 65392, length 296: HTTP
E..P..#.#.5{...........Pj.o:....P..p....Cache-Control: max-age=0
Host: 192.168.1.136
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Connection: keep-alive
User-Agent: LuaSocket 3.0-rc1
TE: trailers
Accept-Language: en-US,en;q=0.9
18:24:24.125746 IP 192.168.1.140.41894 > 192.168.1.136.http: Flags [P.], seq 151:447, ack 1, win 65392, length 296: HTTP
E..P..#.#.5z...........Pj.o:....P..p....Cache-Control: max-age=0
Host: 192.168.1.136
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Connection: keep-alive
User-Agent: LuaSocket 3.0-rc1
TE: trailers
Accept-Language: en-US,en;q=0.9
18:24:24.575743 IP 192.168.1.140.41894 > 192.168.1.136.http: Flags [P.], seq 151:447, ack 1, win 65392, length 296: HTTP
E..P..#.#.5y...........Pj.o:....P..p....Cache-Control: max-age=0
Host: 192.168.1.136
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Connection: keep-alive
User-Agent: LuaSocket 3.0-rc1
TE: trailers
Accept-Language: en-US,en;q=0.9
18:24:25.495791 IP 192.168.1.140.41894 > 192.168.1.136.http: Flags [P.], seq 151:447, ack 1, win 65392, length 296: HTTP
E..P..#.#.5x...........Pj.o:....P..p....Cache-Control: max-age=0
Host: 192.168.1.136
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Connection: keep-alive
User-Agent: LuaSocket 3.0-rc1
TE: trailers
Accept-Language: en-US,en;q=0.9
18:24:27.328180 ARP, Request who-has 192.168.1.136 tell 192.168.1.1, length 46
........`.'.................>.[p.....!.....
>.
18:24:27.335732 IP 192.168.1.140.41894 > 192.168.1.136.http: Flags [P.], seq 151:447, ack 1, win 65392, length 296: HTTP
E..P..#.#.5w...........Pj.o:....P..p....Cache-Control: max-age=0
Host: 192.168.1.136
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Connection: keep-alive
User-Agent: LuaSocket 3.0-rc1
TE: trailers
Accept-Language: en-US,en;q=0.9
Just to follow up on this - it turns out the device I was sending the message to was spontaneously restarting as soon as it read the first part of the message - thus its failure to receive the rest and respond. Obviously a bug in their firmware, and unfortunately Shelly wasn't too interested in fixing it after several messages and data dumps sent to their tech support.

Multiple get requests in a http request

When looking at client->server interaction for fetching images, I see the following HTTP GET request from client where the packet contains 2 HTTP GET requests and I am not sure how the server would respond to such requests?
Will the server ignore the second GET request?
Will the server send the response one by one to each GET request?
This doesn't seem to be HTTP pipelining. Please advise if it is.
Transmission Control Protocol, Src Port: 59649 (59649), Dst Port: 8080 (8080), Seq: 1, Ack: 1, Len: 648
Source Port: 59649
Destination Port: 8080
[Stream index: 86]
[TCP Segment Len: 648]
Sequence number: 1 (relative sequence number)
[Next sequence number: 649 (relative sequence number)]
Acknowledgment number: 1 (relative ack number)
Header Length: 32 bytes
Flags: 0x018 (PSH, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Nonce: Not set
.... 0... .... = Congestion Window Reduced (CWR): Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 1... = Push: Set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...0 = Fin: Not set
[TCP Flags: *******AP***]
Window size value: 683
[Calculated window size: 43712]
[Window size scaling factor: 64]
Checksum: [validation disabled]
[Good Checksum: False]
[Bad Checksum: False]
Urgent pointer: 0
Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
No-Operation (NOP)
Type: 1
0... .... = Copy on fragmentation: No
.00. .... = Class: Control (0)
...0 0001 = Number: No-Operation (NOP) (1)
No-Operation (NOP)
Type: 1
0... .... = Copy on fragmentation: No
.00. .... = Class: Control (0)
...0 0001 = Number: No-Operation (NOP) (1)
Timestamps: TSval 6345, TSecr 6344
Kind: Time Stamp Option (8)
Length: 10
Timestamp value: 6345
Timestamp echo reply: 6344
[SEQ/ACK analysis]
[iRTT: 0.000099000 seconds]
[Bytes in flight: 648]
Hypertext Transfer Protocol
GET HTTP/1.1\r\n
[Expert Info (Chat/Sequence): GET HTTP/1.1\r\n]
[GET HTTP/1.1\r\n]
[Severity level: Chat]
[Group: Sequence]enter code here
Request Method: GET
Request URI:
Request Version: HTTP/1.1
Host: \r\n
sent: \r\n
User-Agent: \r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: en-GB,*\r\n
Connection: keep-alive\r\n
\r\n
[Full request URI: ]
[HTTP request 2/2]
[Prev request in frame: 1254]
[Response in frame: 1272]
Hypertext Transfer Protocol
GET \r\n
[Expert Info (Chat/Sequence): GET HTTP/1.1\r\n]
[GET HTTP/1.1\r\n]
[Severity level: Chat]
[Group: Sequence]
Request Method: GET
Request URI:
Request Version: HTTP/1.1
Host: \r\n
sent: \r\n
User-Agent: \r\n
Accept-Encoding: gzip, deflate\r\n
Accept-Language: en-GB,*\r\n
Connection: keep-alive\r\n
\r\n
[Full request URI: ]
[HTTP request 2/2]
[Prev request in frame: 1254]
[Response in frame: 1272]
Are there any online tool that I can use to test such requests?
It is perfectly acceptable for multiple HTTP requests to be in a single TCP packet, if they fit.
What you are seeing is indeed HTTP pipelining, which is covered in RFC 2616 Section 8 and RFC 7230 Section 6.3.2 of the HTTP 1.1 spec. The client is sending a new GET request without first waiting for a response to a previous GET request. That is the very definition of pipelining:
HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time.
TCP is just optimizing things by using a single TCP packet for both HTTP requests. The client likely has send coalescing (aka the "Nagle algorithm") enabled (which most socket libraries do by default) to reduce network traffic.
In order for the server to respond to pipelined requests, a persistent connection MUST be used, which is another requirement of pipelining, and is clearly visible in your example (the Connection: keep-alive request header).
TCP is a byte stream, the lower level TCP framing does not matter to the higher level protocol layers. A properly written HTTP receiver will be able to separate the individual HTTP messages regardless of the TCP framing used, and process them individually as needed. The HTTP 1.1 spec requires all requests to be responded to in the same order that they were received (HTTP 2.0 changes that, but that is a much more involved process to handle - multiplexing - which I won't get into).
So, to answer your questions:
Will the server ignore the second GET request? - NO
Will the server send the response one by one to each GET request? - YES
This doesn't seem to be HTTP pipelining. Please advise if it is. - IT IS, but not for the reason you are thinking.

What's wrong with this HTTP request?

I am sending the following HTTP request:
POST /input/8dZ8bgapvjfYzmwWno6W.txt HTTP/1.1
Host: data.sparkfun.com
Phant-Private-Key: pz5ga4pkydHgpEb8v608
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 7
temp=44
In my code, I am sending it using UART tx requests to the xbee module, for which the translates to:
POST /input/8dZ8bgapvjfYzmwWno6Wr.txt HTTP/1.1\r\n
Host: data.sparkfun.com\r\n
Phant-Private-Key: pz5ga4pkydHgpEb8v608\r\n
Connection: close\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 7\r\n
\r\n
temp=44
This is to communicate to the phant dataserver at data.sparkfun.com, and it responds with the following data:
HTTP/1.0 400 Bad request
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>400 Bad request</h1>
Your browser sent an invalid request.
</body></html>
I found the answer:
The packet is correct.
While configuring the Xbee Wifi module using XCTU, I had to give the correct port numbers of the server and client Xbee, which were wrong.
Server was 80, client was any port I think.

Http protocol content-length

I am working on a simple download application. While making a request for the following file both firefox and my application doesn't get the content-length field. But if i make the request using wget server does send the content-length field. I did change wgets user agent string to test and it still got the content-length field.
Any ideas why this is happening?
wget request
---request begin---
GET /dc-13/video/2005_Defcon_V2-P_Zimmerman-Unveiling_My_Next_Big_Project.mp4 HTTP/1.0
User-Agent: test
Accept: */*
Host: media.defcon.org
Connection: Keep-Alive
---request end---
HTTP request sent, awaiting response...
---response begin---
HTTP/1.0 200 OK
Server: lighttpd
Date: Sun, 05 Apr 2009 04:40:08 GMT
Last-Modified: Tue, 23 May 2006 22:18:19 GMT
Content-Type: video/mp4
Content-Length: 104223909
Connection: keep-alive
firefox request
GET /dc-13/video/2005_Defcon_V2-P_Zimmerman-Unveiling_My_Next_Big_Project.mp4 HTTP/1.1
Host: media.defcon.org
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.0.8) Gecko/2009032608 Firefox/3.0.8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://www.defcon.org/html/links/defcon-media-archives.html
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.x 200 OK
Server: lighttpd
Date: Sun, 05 Apr 2009 05:20:12 GMT
Last-Modified: Tue, 23 May 2006 22:18:19 GMT
Content-Type: video/mp4
Transfer-Encoding: chunked
Update:
Is there a header that I can send that will tell Lighthttpd not to use chunked encoding.My original problem is that I am using urlConnection to grab the file in my java application which automatically sends HTTP 1.1 request.
I would like to know the size of the file so i can update my percentage.
GET
/dc-13/video/2005_Defcon_V2-P_Zimmerman-Unveiling_My_Next_Big_Project.mp4
HTTP/1.1
Firefox is performing an HTTP 1.1 GET request. Lighthttpd understands that the client will support chunked-transfer encoding and returns the content in chunks, with each chunk reporting its own length.
GET
/dc-13/video/2005_Defcon_V2-P_Zimmerman-Unveiling_My_Next_Big_Project.mp4
HTTP/1.0
Wget on the other hand performs an HTTP 1.0 GET request. Lighthttpd, understanding that the client doesn't support HTTP 1.1 (and thus chunked-transfer encoding), returns the content in one single chunk, with the length reported in the response header.
Looks like it's because of the chunked transfer encoding:
Transfer-Encoding: chunked
This will send the video down in chunks, each with its own size. This is defined in HTTP 1.1, which is what Firefox is using, while wget is using HTTP 1.0, which doesn't support chunked transfer encoding, so the server has to send the whole file at once.
I was having the same problem and found a solution regardless of which HTTP version:
First use a HEAD request to the server which correctly responds with just the HTTP header and no contents. This header correctly includes the wanted Content-Length: bytes size for the file to download.
Proceed with the GET request to download the file (the header from the GET response fails to include Content-length).
An Objective-C language example:
NSString *zipURL = #"http://1.bp.blogspot.com/_6-cw84gcURw/TRNb3PDWneI/AAAAAAAAAYM/YFCZP1foTiM/s1600/paragliding1.jpg";
NSURL *url = [NSURL URLWithString:zipURL];
// Configure the HTTP request for HEAD header fetch
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
urlRequest.HTTPMethod = #"HEAD"; // Default is "GET"
// Define response class
__autoreleasing NSHTTPURLResponse *response;
// Send HEAD request to server
NSData *contentsData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];
// Header response field
NSDictionary *headerDeserialized = response.allHeaderFields;
// The contents length
int contents_length = [(NSString*)headerDeserialized[#"Content-Length"] intValue];
//printf("HEAD Response header: %s\n",headerDeserialized.description.UTF8String);
printf("HEAD:\ncontentsData.length: %d\n",contentsData.length);
printf("contents_length = %d\n\n",contents_length);
urlRequest.HTTPMethod = #"GET";
// Send "GET" to download file
contentsData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];
// Header response field
headerDeserialized = response.allHeaderFields;
// The contents length
contents_length = [(NSString*)headerDeserialized[#"Content-Length"] intValue];
printf("GET Response header: %s\n",headerDeserialized.description.UTF8String);
printf("GET:\ncontentsData.length: %d\n",contentsData.length);
printf("contents_length = %d\n",contents_length);
return;
And the output:
HEAD:
contentsData.length: 0
contents_length = 146216
GET:
contentsData.length: 146216
contents_length = 146216
(Note: This example URL does correctly provides the header Content-Length from the GET response, but shows the idea if it failed to)

Resources