Menu

#1319 Issue with using http_extra_header with certain plugins

v1.0 (example)
closed-fixed
None
5
2024-05-27
2024-04-22
No

We wanted to start sending an additional http header with our soap requests, so we tried using the documented http_extra_header struct value. It worked until we tried it with the gsoapWinInet plugin enabled, after which all requests started immediately returning as timed out (as it the calls would return right away saying the timeout had passed). After some debugging I was able to track the reason down to the soap_puthttphdr function in stdsoap2.cpp. For the http_extra_header header(s) only it doesn't call the soap->fposthdr callback that the plugins register and instead directly calls soap_send. This results in the wininet plugin never getting the header to apply it, and also results in a mismatch in buffer sizes inside it and core gsoap which makes the plugin believe that it is waiting for more data when the post call is made, so it immediately returns. I replaced the if (soap->http_extra_header) section of soap_puthttphdr with code that loops over the extra header string calling the soap->fposthdr function for each header instead and then everything started working as expected for me.

Discussion

  • Robert van Engelen

    Thanks for the feedback. The problem is that the extra header is allowed to contain more than one header string i.e. with \r\n separators. This won't work woth the fposthdr callback. That's why it differs. And yes, it is a bit ugly. Your suggestion to use a loop over the strings could work to use fposthder.

     

    Last edit: Robert van Engelen 2024-04-23
  • Robert van Engelen

    • assigned_to: Robert van Engelen
     
  • Robert van Engelen

    This modification should work, I've tested with various examples including incorrect ones (which won't show up as a header):

      if (soap->http_extra_header)
      {
        const char *header = soap->http_extra_header;
        soap->http_extra_header = NULL; /* use http_extra_header once (assign new value before each call) */
        while (*header)
        {
          const char *s = strchr(header, ':');
          const char *t = strchr(header, '\n');
          if (t == NULL)
            t = header + strlen(header);
          if (s != NULL && s < t && t < header + sizeof(soap->tmpbuf))
          {
            while (s < t && isspace(*(t - 1)))
              --t;
            soap_strncpy(soap->tmpbuf, sizeof(soap->tmpbuf), header, t - header);
            soap->tmpbuf[s - header] = '\0';
            while (s < t && isspace(*++s))
              continue;
            err = soap->fposthdr(soap, soap->tmpbuf, soap->tmpbuf + (s - header));
            if (err)
              return err;
          }
          while (isspace(*t))
            ++t;
          header = t;
        }
      }
    

    Note that fposthdr is used with some plugins, but extra header as it was does not affect these other plugins. So only WinInet benefits from this change.

     
  • Robert van Engelen

    • status: open --> open-fixed
     
  • Robert van Engelen

    • status: open-fixed --> closed-fixed
     

Log in to post a comment.