Skip to content

Commit 2505f08

Browse files
authored
added optional Content-Type from the Buddy reply to pass it to client; fixed #3517 (#3955)
1 parent 6cf5180 commit 2505f08

File tree

6 files changed

+64
-47
lines changed

6 files changed

+64
-47
lines changed

src/netreceive_http.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ void HttpServe ( std::unique_ptr<AsyncNetBuffer_c> pBuf )
184184
{
185185
if ( IsEmpty ( sMsg ) )
186186
{
187-
HttpBuildReply ( dResult, eCode, sMsg, false );
187+
HttpReplyTrait_t tReply { eCode, sMsg };
188+
HttpBuildReply ( tReply, dResult );
188189
} else
189190
{
190191
LogNetError ( sMsg.first );

src/searchdaemon.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1391,7 +1391,19 @@ void LogToConsole(const char* szKind, const char* szMsg) noexcept;
13911391
void SetLogHttpFilter ( const CSphString & sVal );
13921392
int HttpGetStatusCodes ( EHTTP_STATUS eStatus ) noexcept;
13931393
EHTTP_STATUS HttpGetStatusCodes ( int iStatus ) noexcept;
1394-
void HttpBuildReply ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, const char * sBody, int iBodyLen, bool bHtml );
1394+
1395+
struct HttpReplyTrait_t
1396+
{
1397+
EHTTP_STATUS m_eCode = EHTTP_STATUS::_503;
1398+
Str_t m_sBody;
1399+
bool m_bHtml = false;
1400+
bool m_bHeadReply = false;
1401+
const char * m_sContentType = nullptr;
1402+
};
1403+
1404+
void HttpBuildReply ( const HttpReplyTrait_t & tReply, CSphVector<BYTE> & dData );
1405+
void ReplyBuf ( const HttpReplyTrait_t & tReply, CSphVector<BYTE> & dData );
1406+
13951407
void HttpBuildReplyHead ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, const char * sBody, int iBodyLen, bool bHeadReply );
13961408
void HttpErrorReply ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, const char * szError );
13971409

src/searchdbuddy.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ struct BuddyReply_t
632632
CSphString m_sType;
633633
JsonObj_c m_tMessage;
634634
int m_iReplyHttpCode = 0;
635+
CSphString m_sContentType;
635636
};
636637

637638
static bool ParseReply ( char * sReplyRaw, BuddyReply_t & tParsed, CSphString & sError )
@@ -673,6 +674,9 @@ static bool ParseReply ( char * sReplyRaw, BuddyReply_t & tParsed, CSphString &
673674
if ( !tParsed.m_tRoot.FetchIntItem ( tParsed.m_iReplyHttpCode, "error_code", sError, false ) )
674675
return false;
675676

677+
if ( !tParsed.m_tRoot.FetchStrItem ( tParsed.m_sContentType, "content_type", sError, true ) )
678+
return false;
679+
676680
return true;
677681
}
678682

@@ -824,7 +828,11 @@ bool ProcessHttpQueryBuddy ( HttpProcessResult_t & tRes, Str_t sSrcQuery, Option
824828
EHTTP_STATUS eHttpStatus = GetHttpStatusCode ( tReplyParsed.m_iReplyHttpCode, tRes.m_eReplyHttpCode );
825829

826830
dResult.Resize ( 0 );
827-
ReplyBuf ( FromStr ( sDump ), eHttpStatus, bNeedHttpResponse, dResult );
831+
832+
HttpReplyTrait_t tReplyBuf { eHttpStatus, sDump };
833+
tReplyBuf.m_bHtml = bNeedHttpResponse;
834+
tReplyBuf.m_sContentType = tReplyParsed.m_sContentType.cstr();
835+
ReplyBuf ( tReplyBuf, dResult );
828836

829837
if ( SetSessionMeta ( tReplyParsed.m_tRoot ) )
830838
LogBuddyQuery ( sSrcQuery, BuddyQuery_e::HTTP );

src/searchdhttp.cpp

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -111,43 +111,42 @@ inline constexpr const char* HttpGetStatusName ( EHTTP_STATUS eStatus ) noexcept
111111
};
112112
}
113113

114-
extern CSphString g_sMySQLVersion;
115-
116-
static void HttpBuildReply ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, const char * sBody, int iBodyLen, bool bHtml, bool bHeadReply )
114+
void HttpBuildReply ( const HttpReplyTrait_t & tReply, CSphVector<BYTE> & dData )
117115
{
118-
assert ( sBody && iBodyLen );
116+
assert ( tReply.m_sBody.first && tReply.m_sBody.second );
117+
118+
const char * sContentType = tReply.m_sContentType;
119+
if ( !sContentType )
120+
sContentType = ( tReply.m_bHtml ? "text/html" : "application/json" );
119121

120-
const char * sContent = ( bHtml ? "text/html" : "application/json" );
121122
CSphString sHttp;
122-
sHttp.SetSprintf ( "HTTP/1.1 %s\r\nServer: %s\r\nContent-Type: %s; charset=UTF-8\r\nContent-Length:%d\r\n\r\n", HttpGetStatusName(eCode), g_sMySQLVersion.cstr(), sContent, iBodyLen );
123+
sHttp.SetSprintf ( "HTTP/1.1 %s\r\nServer: %s\r\nContent-Type: %s; charset=UTF-8\r\nContent-Length:%d\r\n\r\n", HttpGetStatusName ( tReply.m_eCode ), g_sStatusVersion.cstr(), sContentType, tReply.m_sBody.second );
123124

124125
int iHeaderLen = sHttp.Length();
125126
int iBufLen = iHeaderLen;
126-
if ( !bHeadReply )
127-
iBufLen += iBodyLen;
127+
if ( !tReply.m_bHeadReply )
128+
iBufLen += tReply.m_sBody.second;
128129
dData.Resize ( iBufLen );
129130
memcpy ( dData.Begin(), sHttp.cstr(), iHeaderLen );
130-
if ( !bHeadReply )
131-
memcpy ( dData.Begin() + iHeaderLen, sBody, iBodyLen );
132-
}
133-
134-
void HttpBuildReply ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, const char * sBody, int iBodyLen, bool bHtml )
135-
{
136-
HttpBuildReply ( dData, eCode, sBody, iBodyLen, bHtml, false );
131+
if ( !tReply.m_bHeadReply )
132+
memcpy ( dData.Begin() + iHeaderLen, tReply.m_sBody.first, tReply.m_sBody.second );
137133
}
138134

139135
void HttpBuildReplyHead ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, const char * sBody, int iBodyLen, bool bHeadReply )
140136
{
141-
HttpBuildReply ( dData, eCode, sBody, iBodyLen, false, bHeadReply );
137+
HttpReplyTrait_t tReply { eCode, Str_t ( sBody, iBodyLen ) };
138+
tReply.m_bHeadReply = bHeadReply;
139+
HttpBuildReply ( tReply, dData );
142140
}
143141

144-
145142
void HttpErrorReply ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, const char * szError )
146143
{
147144
JsonObj_c tErr;
148145
tErr.AddStr ( "error", szError );
149146
CSphString sJsonError = tErr.AsString();
150-
HttpBuildReply ( dData, eCode, sJsonError.cstr(), sJsonError.Length(), false );
147+
148+
HttpReplyTrait_t tReply { eCode, FromStr ( sJsonError ) };
149+
HttpBuildReply ( tReply, dData );
151150
}
152151

153152
struct Endpoint_t
@@ -466,18 +465,6 @@ CSphString HttpEndpointToStr ( EHTTP_ENDPOINT eEndpoint )
466465
return g_dEndpoints[(int)eEndpoint].m_szName1;
467466
}
468467

469-
void HttpBuildReply ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, Str_t sReply, bool bHtml )
470-
{
471-
const char * sContent = ( bHtml ? "text/html" : "application/json" );
472-
StringBuilder_c sHttp;
473-
sHttp.Sprintf ( "HTTP/1.1 %s\r\nServer: %s\r\nContent-Type: %s; charset=UTF-8\r\nContent-Length: %d\r\n\r\n", HttpGetStatusName ( eCode ), g_sStatusVersion.cstr(), sContent, sReply.second );
474-
475-
dData.Reserve ( sHttp.GetLength() + sReply.second );
476-
dData.Append ( (Str_t)sHttp );
477-
dData.Append ( sReply );
478-
}
479-
480-
481468
HttpRequestParser_c::HttpRequestParser_c()
482469
{
483470
http_parser_settings_init ( &m_tParserSettings );
@@ -892,7 +879,10 @@ static void HttpHandlerIndexPage ( CSphVector<BYTE> & dData )
892879
{
893880
StringBuilder_c sIndexPage;
894881
sIndexPage.Appendf ( g_sIndexPage, g_sStatusVersion.cstr() );
895-
HttpBuildReply ( dData, EHTTP_STATUS::_200, (Str_t)sIndexPage, true );
882+
883+
HttpReplyTrait_t tReply { EHTTP_STATUS::_200, (Str_t)sIndexPage };
884+
tReply.m_bHtml = true;
885+
HttpBuildReply ( tReply, dData );
896886
}
897887

898888
//////////////////////////////////////////////////////////////////////////
@@ -1025,14 +1015,16 @@ StmtErrorReporter_i * CreateHttpErrorReporter()
10251015
//////////////////////////////////////////////////////////////////////////
10261016
// all the handlers for http queries
10271017

1028-
void ReplyBuf ( Str_t sResult, EHTTP_STATUS eStatus, bool bNeedHttpResponse, CSphVector<BYTE> & dData )
1018+
void ReplyBuf ( const HttpReplyTrait_t & tReply, CSphVector<BYTE> & dData )
10291019
{
1030-
if ( bNeedHttpResponse )
1031-
HttpBuildReply ( dData, eStatus, sResult, false );
1020+
if ( tReply.m_bHtml )
1021+
{
1022+
HttpBuildReply ( tReply, dData );
1023+
}
10321024
else
10331025
{
10341026
dData.Resize ( 0 );
1035-
dData.Append ( sResult );
1027+
dData.Append ( tReply.m_sBody );
10361028
}
10371029
}
10381030

@@ -1109,25 +1101,29 @@ void HttpHandler_c::ReportError ( const char * sError, HttpErrorType_e eType, EH
11091101
void HttpHandler_c::BuildReply ( const CSphString & sResult, EHTTP_STATUS eStatus )
11101102
{
11111103
m_eHttpCode = eStatus;
1112-
ReplyBuf ( FromStr ( sResult ), eStatus, m_bNeedHttpResponse, m_dData );
1104+
HttpReplyTrait_t tReply { eStatus, FromStr ( sResult ), m_bNeedHttpResponse };
1105+
ReplyBuf ( tReply, m_dData );
11131106
}
11141107

11151108
void HttpHandler_c::BuildReply ( const char* szResult, EHTTP_STATUS eStatus )
11161109
{
11171110
m_eHttpCode = eStatus;
1118-
ReplyBuf ( FromSz( szResult ), eStatus, m_bNeedHttpResponse, m_dData );
1111+
HttpReplyTrait_t tReply { eStatus, FromSz( szResult ), m_bNeedHttpResponse };
1112+
ReplyBuf ( tReply, m_dData );
11191113
}
11201114

11211115
void HttpHandler_c::BuildReply ( const StringBuilder_c & sResult, EHTTP_STATUS eStatus )
11221116
{
11231117
m_eHttpCode = eStatus;
1124-
ReplyBuf ( (Str_t)sResult, eStatus, m_bNeedHttpResponse, m_dData );
1118+
HttpReplyTrait_t tReply { eStatus, (Str_t)sResult, m_bNeedHttpResponse };
1119+
ReplyBuf ( tReply, m_dData );
11251120
}
11261121

11271122
void HttpHandler_c::BuildReply ( Str_t sResult, EHTTP_STATUS eStatus )
11281123
{
11291124
m_eHttpCode = eStatus;
1130-
ReplyBuf ( sResult, eStatus, m_bNeedHttpResponse, m_dData );
1125+
HttpReplyTrait_t tReply { eStatus, sResult, m_bNeedHttpResponse };
1126+
ReplyBuf ( tReply, m_dData );
11311127
}
11321128

11331129
// check whether given served index is exist and has requested type
@@ -2498,7 +2494,9 @@ void sphHttpErrorReply ( CSphVector<BYTE> & dData, EHTTP_STATUS eCode, const cha
24982494
JsonObj_c tErr;
24992495
tErr.AddStr ( "error", szError );
25002496
CSphString sJsonError = tErr.AsString();
2501-
HttpBuildReply ( dData, eCode, FromStr (sJsonError), false );
2497+
2498+
HttpReplyTrait_t tReply { eCode, FromStr ( sJsonError ) };
2499+
HttpBuildReply ( tReply, dData );
25022500
}
25032501

25042502
static void EncodePercolateMatchResult ( const PercolateMatchResult_t & tRes, const CSphFixedVector<int64_t> & dDocids, const CSphString & sIndex, JsonEscapedBuilder & tOut )

src/searchdhttp.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ class HttpRequestParser_c : public ISphNoncopyable
7979
http_parser m_tParser;
8080
};
8181

82-
void HttpBuildReply ( CSphVector<BYTE>& dData, EHTTP_STATUS eCode, Str_t sReply, bool bHtml );
83-
8482
///////////////////////////////////////////////////////////////////////
8583
/// Stream reader
8684
class CharStream_c
@@ -117,7 +115,6 @@ struct HttpProcessResult_t
117115
CSphString m_sError;
118116
};
119117

120-
void ReplyBuf ( Str_t sResult, EHTTP_STATUS eStatus, bool bNeedHttpResponse, CSphVector<BYTE> & dData );
121118
HttpProcessResult_t ProcessHttpQuery ( CharStream_c & tSource, Str_t & sSrcQuery, OptionsHash_t & hOptions, CSphVector<BYTE> & dResult, bool bNeedHttpResponse, http_method eRequestType );
122119

123120
namespace bson {

src/searchdhttpcompat.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1679,7 +1679,8 @@ static bool EmulateIndexCount ( const CSphString & sIndex, const nljson & tReq,
16791679
tRes["hits"]["total"]["value"] = iDocsTotal;
16801680

16811681
std::string sRes = tRes.dump();
1682-
HttpBuildReply ( dResult, EHTTP_STATUS::_200, sRes.c_str(), sRes.length(), false );
1682+
HttpReplyTrait_t tReply { EHTTP_STATUS::_200, FromSz ( sRes.c_str() ) };
1683+
HttpBuildReply ( tReply, dResult );
16831684

16841685
return true;
16851686
}

0 commit comments

Comments
 (0)