Search code examples
rubycharles-proxy

Trying to replicate Mobile App POST Request in Ruby, Getting 502 Gateway Error


I'm trying to automate actions I can take manually in an iPhone app using Ruby, but when I do, I get a 502 bad gateway error.

Using Charles Proxy I got the request the iPhone app is making:

POST /1.1/user/-/friends/invitations HTTP/1.1
Host: redacted.com
Accept-Locale: en_US
Accept: */*
Authorization: Bearer REDACTED
Content-Encoding: gzip
Accept-Encoding: br, gzip, deflate
Accept-Language: en_US
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 66
Connection: keep-alive
X-App-Version: 814

invitedUserId=REDACTED&source=PROFILE_INVITATION

I wrote the following code in Ruby to send this same request:

@header_post = {
  "Host" => "redacted.com",
  "Accept-Locale" => "en_US",
  "Accept" => "*/*",
  "Authorization" => "Bearer REDACTED",
  "Content-Encoding" => "gzip",
  "Accept-Encoding" => "br, gzip, deflate",
  "Accept-Language" => "en_US",
  "Content-Type" => "application/x-www-form-urlencoded; charset=UTF-8",
  "Connection" => "keep-alive",
  "X-App-Version" => "814"
}
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
path = '/1.1/user/-/friends/invitations'

data = "invitedUserId=REDACTED&source=PROFILE_INVITATION"

resp, data = http.post(path, data, @header_post)

Unfortunately I get a 502 Bad Gateway Error when running this code.

One thing I noticed which I think is key to the solution here is that, in the POST request the mobile app is making, the content length is 66. But the length of the string "invitedUserId=REDACTED&source=PROFILE_INVITATION" with un-redacted userId is only 46.

Am I missing another form variable with format "&param=value" which has length 20? Or am I missing something else?

Thank you in advance!


Solution

  • This is probably not directly tied to the body length you're sending.

    I see possibly 2 problems here :

    • the 502 error : are your uri.host and port correct ? A 502 error means there is something wrong on the server side. Also try by removing the Host header.
    • body content is not gzipped

    You're defining an header Content-Encoding: gzip but you didn't compress the data (Net::Http doesn't do that automatically).

    Try with something like that :

    require "gzip"
    
    @header_post = { 
      # ... 
    }
    
    http = Net::HTTP.new(uri.host, uri.port)
    path = '/1.1/user/-/friends/invitations'
    
    data = "invitedUserId=REDACTED&source=PROFILE_INVITATION"
    
    # instanciate a new gzip buffer
    gzip = Zlib::GzipWriter.new(StringIO.new)
    
    # append your data
    gzip << data
    
    # get the gzip body and use it in your request
    body = gzip.close.string
    resp, data = http.post(path, body, @header_post)
    

    Alternatively, maybe the server is accepting a non-gzipped content. You could try simply by deleting the Content-Encoding error from your original code.

    However if it was the only mistake, the server should not send a 502 but a 4xx error. So I'm guessing there is another issue there with the uri config like a suggested above.