-
Notifications
You must be signed in to change notification settings - Fork 304
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
HPCC-30942 Fix SOAPCALL handling of lowercase HTTP headers in response #18095
Conversation
@ghalliday draft PR hasn't been tested yet. For your initial review.. and to make sure compiles on windows, etc. |
common/thorhelper/thorsoapcall.cpp
Outdated
return true; | ||
if (strstr(httpheaders, match)) | ||
if (strcasestr(httpheaders, match)) |
There was a problem hiding this comment.
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()?
https://track.hpccsystems.com/browse/HPCC-30942 |
Signed-off-by: Anthony Fishbeck <[email protected]>
f2ee204
to
9c44801
Compare
* 07/04/95 Bob Stout ANSI-fy | ||
* 02/03/94 Fred Cole Original | ||
*/ | ||
|
There was a problem hiding this comment.
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.
@ghalliday not sure which release you'd like to target for this. |
There was a problem hiding this 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; |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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;
There was a problem hiding this comment.
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 */ |
There was a problem hiding this comment.
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 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be nlen!
There was a problem hiding this comment.
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 */ |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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")) |
There was a problem hiding this comment.
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).
@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? |
I will merge as-is, but have created a jira to go back and clean it up. |
Type of change:
Checklist:
Smoketest:
Testing: