0

i'm new to benthos, hope following configuration to work, i looked at the benthos doc and tried to google, but didn't find an answer, any answer is greatly appreciated

actually, the sign will be the calculated value, but now I'm stuck on the first step, i can't get the sign value to be successfully assigned to the header

input:
  processors:
   - bloblang: |
      meta sign = "1233312312312312"
      meta device_id = "31231312312"
  http_client:
    url: >-
      https://test/${!meta("device_id")}
    verb: GET
    headers: 
      sign: ${!meta("sign")}

after @Mihai Todor helped, now i have new question.

this config below can work.(first)

input:
  http_client:
    url: >-
      https://test/api
    verb: GET
    headers: 
      sign: "signcode"

but this one returned invalid signature error

input:
  mapping: root = {}
  generate:
    count: 1
pipeline:
  processors:
    - http:
        url: >-
          https://test/api
        verb: GET
        headers:
          sign: "signcode"
output:
  stdout: {}

update(more detail screenshot)

first

second


Finally i got it work with the @Mihai helped.

the reason why i got 'signure is invaild' is because a space character in paramter headers->stringToSign, for reason i need add paramter 'stringTosign' and the value need to be empty, but somehow i copy an invisible space character in it, this will make benthos to add a Content-Length: 1 to the request header(i don't know why), this Content-Length: 1 cause my request always failed with error 'signure invaild'.

after i deleted the space character, all is ok.

Oliver
  • 3
  • 2

1 Answers1

0

Input processors operate on the messages returned by the input, so you can't set metadata that way. Also, metadata is associated with in-flight messages and doesn't persist across messages (use an in-memory cache if you need that).

One workaround is to combine a generate input with an http processor like so:

input:
  generate:
    mapping: root = ""
    interval: 0s
    count: 1

  processors:
    - mapping: |
        meta sign = "1233312312312312"
        meta device_id = "31231312312"
        
pipeline:
  processors:
    - http:
        url: >-
          https://test/${!meta("device_id")}
        verb: GET
        headers:
          sign: ${!meta("sign")}

output:
  stdout: {}

Note that the mapping processor (the replacement for the soon-to-be deprecated bloblang one) can also reside under pipeline.processors, and, if you just need to set those metadata fields, you can also do it inside the mapping field of the generate input (root = {} is implicit).

Update: Following the comments, I ran two configs and used nc to print the full HTTP request each of them make:

  1. generate input with http processor:
input:
  generate:
    mapping: root = ""
    interval: 0s
    count: 1

  processors:
    - mapping: |
        meta sign = "1233312312312312"
        meta device_id = "31231312312"

pipeline:
  processors:
    - http:
        url: >-
          http://localhost:6666/${!meta("device_id")}
        verb: GET
        headers:
          sign: ${!meta("sign")}

output:
  stdout: {}

HTTP request dump:

> nc -l localhost 6666
GET /31231312312 HTTP/1.1
Host: localhost:6666
User-Agent: Go-http-client/1.1
Sign: 1233312312312312
Accept-Encoding: gzip

  1. http_client input:
input:
  http_client:
    url: >-
      http://localhost:6666/31231312312
    verb: GET
    headers:
      sign: 1233312312312312

output:
  stdout: {}

HTTP request dump:

> nc -l localhost 6666
GET /31231312312 HTTP/1.1
Host: localhost:6666
User-Agent: Go-http-client/1.1
Sign: 1233312312312312
Accept-Encoding: gzip

I used Benthos v4.5.1 on OSX and, for both configs, the request looks identical.

My best guess is that you're seeing a transitive issue on your end (some rate limiting perhaps).

Mihai Todor
  • 8,014
  • 9
  • 49
  • 86
  • thanks for your answer, this made me understand a lot, but when i use the code above, seems the sign in headers can't be use for the http request, even if i paste the sign string directly to the headers->sign. are there any details I've overlooked? – Oliver Aug 18 '22 at 06:48
  • You're welcome! It's hard to say what might be wrong without being able to run it myself. I suggest increasing the logging level https://www.benthos.dev/docs/components/logger/about to see if you can get any extra information. If not, you can always dump messages using the `log` processor with smth like `message: ${! content() }` and you can check for mapping errors with `message: ${! error() }`. Finally, you can try using smth like tcpdump to inspect the http calls that are made by Benthos. – Mihai Todor Aug 18 '22 at 10:07
  • Yes, it's hard to know where the error is without being able to execute the config file. I'm just confused about the code, the first code(question updated) can be executed successfully, but the second one returns invalid signature I will try to trace the logs, thanks anyway – Oliver Aug 18 '22 at 10:26
  • Your updated config can't work because it's missing `mapping: root = {}` in the `generate` input. Besides that, I really don't see how the `http_client` input would be different from using the `http` processor. Please share more details. – Mihai Todor Aug 18 '22 at 11:23
  • ok, my bad, i just pasted it into the question and left out the mapping: root = {}, my local configuration has it, i'll provide more details and update question soon. – Oliver Aug 18 '22 at 11:52
  • Ah, it's probably because `root = {}` ends up creating an empty JSON, namely `{}`, which will get written to the HTTP request body. Would you mind trying with `root = ""`? That way, it will resolve to an empty string and not write anything in the body of the request. – Mihai Todor Aug 18 '22 at 13:32
  • i tried it, but not work, i find other params like "access_token" is working, only the field sign cannot be transmitted correctly, this confuses me even more. – Oliver Aug 18 '22 at 16:10
  • OK, I did some more experiments and I really can't see what would make those two configs emit different HTTP requests. See the update I made to my answer. Since you're using HTTPS, I suggest setting up https://mitmproxy.org/ as a localhost proxy between Benthos and that endpoint that you're targeting. It should allow you to view any differences in the request headers & payload. – Mihai Todor Aug 18 '22 at 16:37
  • Finally i got it work, i found the reason with `nc`, really appreciate your patient answer! i'll explain in the question why i got that error – Oliver Aug 19 '22 at 03:38
  • Glad you figured it out :) – Mihai Todor Aug 19 '22 at 10:24