Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HPCC-30942 Fix SOAPCALL handling of lowercase HTTP headers in response #18095

Conversation

afishbeck
Copy link
Member

@afishbeck afishbeck commented Nov 29, 2023

Type of change:

  • This change is a bug fix (non-breaking change which fixes an issue).
  • This change is a new feature (non-breaking change which adds functionality).
  • This change improves the code (refactor or other change that does not change the functionality)
  • This change fixes warnings (the fix does not alter the functionality or the generated code)
  • This change is a breaking change (fix or feature that will cause existing behavior to change).
  • This change alters the query API (existing queries will have to be recompiled)

Checklist:

  • My code follows the code style of this project.
    • My code does not create any new warnings from compiler, build system, or lint.
  • The commit message is properly formatted and free of typos.
    • The commit message title makes sense in a changelog, by itself.
    • The commit is signed.
  • My change requires a change to the documentation.
    • I have updated the documentation accordingly, or...
    • I have created a JIRA ticket to update the documentation.
    • Any new interfaces or exported functions are appropriately commented.
  • I have read the CONTRIBUTORS document.
  • The change has been fully tested:
    • I have added tests to cover my changes.
    • All new and existing tests passed.
    • I have checked that this change does not introduce memory leaks.
    • I have used Valgrind or similar tools to check for potential issues.
  • I have given due consideration to all of the following potential concerns:
    • Scalability
    • Performance
    • Security
    • Thread-safety
    • Cloud-compatibility
    • Premature optimization
    • Existing deployed queries will not be broken
    • This change fixes the problem, not just the symptom
    • The target branch of this pull request is appropriate for such a change.
  • There are no similar instances of the same problem that should be addressed
    • I have addressed them here
    • I have raised JIRA issues to address them separately
  • This is a user interface / front-end modification
    • I have tested my changes in multiple modern browsers
    • The component(s) render as expected

Smoketest:

  • Send notifications about my Pull Request position in Smoketest queue.
  • Test my draft Pull Request.

Testing:

@afishbeck
Copy link
Member Author

@ghalliday draft PR hasn't been tested yet. For your initial review.. and to make sure compiles on windows, etc.

return true;
if (strstr(httpheaders, match))
if (strcasestr(httpheaders, match))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ghalliday not sure if there is JLIB alternative to strcasestr()?

Copy link

@afishbeck afishbeck force-pushed the soapcallCaseInsentiveHTTPResponse branch from f2ee204 to 9c44801 Compare November 30, 2023 23:05
@afishbeck afishbeck marked this pull request as ready for review November 30, 2023 23:05
* 07/04/95 Bob Stout ANSI-fy
* 02/03/94 Fred Cole Original
*/

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ghalliday strcasestr() didn't compile on windows-22. Tweaked a public domain version of stristr(). Let me know if you'd prefer another approach.

@afishbeck afishbeck requested a review from ghalliday November 30, 2023 23:07
@afishbeck
Copy link
Member Author

@ghalliday not sure which release you'd like to target for this.

Copy link
Member

@ghalliday ghalliday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@afishbeck I'm not sure what I think. It is probably the minimal change to fix the bug, but I had been wondering about the implementation of the current functions. (Only spotted because I have been looking at this code recently.)
The stristr function is a good idea, but I think the implementation could be improved. It could also do with some unit tests (along with everything else in the system!)

So we could take it, and then improve/fix the functions as a separate PR, or we could improve them and fix this at the same time.
What are your thoughts?

return nullptr;
}

sptr = start;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the definition of sptr here (delete line 2874):

const char * sptr = start;

}

sptr = start;
pptr = (char *) needle;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the definition of pptr here, and remove the cast.

const char * pptr = needle;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Originally they weren't const strings but I changed it and forgot this one.

const char *pptr = needle; /* Pattern to search for */
const char *start = haystack; /* Start with a bowl of hay */
const char *sptr; /* Substring pointer */
int slen = strlen(haystack); /* Total size of haystack */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slen, plen should really be size_t, not int.

const char *start = haystack; /* Start with a bowl of hay */
const char *sptr; /* Substring pointer */
int slen = strlen(haystack); /* Total size of haystack */
int plen = strlen(needle); /* Length of our needle */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be nlen!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think the p was for pattern. But confusing, and really a prefix of "p" for anything but pointer can be confusing.

/* while string length not shorter than pattern length */
for (; slen >= plen; start++, slen--)
{
/* find start of pattern in string */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would have coded as (untested):

char needle0 := tolower(*needle);
for (; slen >= plen; start++, slen--)
{
   if (tolower(*start) != needle0)
   {
      size_t i = 1;
      for (;;)
      {
           if (i == plen)
              return start;
            if (tolower(start[i] != tolower(needle[i]))
               break;
            i++;
      }   
   }
}
return nullptr;

It depends how important efficiency is (and how clever the c++ compiler is).

@@ -1609,9 +1609,9 @@ bool httpHeaderBlockContainsHeader(const char *httpheaders, const char *header)
return false;
VStringBuffer match("\n%s:", header);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did wonder about recoding this, to walk through checking for matches and then skipping to the next \n. It would avoid creating a temporary string, and would (debatebly) probably be more efficient.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I did do that I would implement a
const char * findHttpHeaderValue(const char *httpheaders, const char *header)
function that returned a pointer to the value, which could then be used in the httpHeaderBlockContainsHeader and getHTTPHeader functions.

@@ -1621,7 +1621,7 @@ bool getHTTPHeader(const char *httpheaders, const char *header, StringBuffer& va
if (!httpheaders || !*httpheaders || !header || !*header)
return false;

const char* pHeader = strstr(httpheaders, header);
const char* pHeader = stristr(httpheaders, header);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't have the same checks as the one above. In particular,

"content-length" would match "\nxcontent-length: 100\n"

@@ -1947,10 +1947,10 @@ class CWSCAsyncFor : implements IWSCAsyncFor, public CInterface, public CAsyncFo
s = strstr(buffer, " ");
if (s)
rval = atoi(s+1);
if (!strstr(buffer,"Transfer-Encoding: chunked"))
if (!stristr(buffer,"Transfer-Encoding: chunked"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should also really be using getHTTPHeader(dbgheader).

@afishbeck
Copy link
Member Author

@afishbeck I'm not sure what I think. It is probably the minimal change to fix the bug, but I had been wondering about the implementation of the current functions. (Only spotted because I have been looking at this code recently.) The stristr function is a good idea, but I think the implementation could be improved. It could also do with some unit tests (along with everything else in the system!)

So we could take it, and then improve/fix the functions as a separate PR, or we could improve them and fix this at the same time. What are your thoughts?

@ghalliday I definitely noticed the code could use improvement. I was trying to minimize the fix to support HAProxy 2.0 thinking the change would likely go into an older branch (not sure how far back). If it were targeting latest I would definitely recommend improving the code right away for this fix I'm not sure. I can add the low risk improvements and open a jira for further refactoring?

@ghalliday
Copy link
Member

I will merge as-is, but have created a jira to go back and clean it up.

@ghalliday ghalliday merged commit 75bbc4e into hpcc-systems:candidate-9.2.x Dec 7, 2023
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants