55 # include <sys/time.h>
60 #define NCBI_USE_ERRCODE_X Cgi_Application
121 m_Request(new
CCgiRequest(args ? args : &app.GetArguments(),
122 env ?
env : &app.GetEnvironment(),
123 inp,
flags, ifd, errbuf_size)),
124 m_Response(
out, ofd),
166 m_Response(
out, ofd),
195 if (!session_storage &&
m_App) {
213 m_Request->SetTrackingCookie(track_cookie_value);
214 bool bad_tracking_cookie =
false;
218 ctx.SetSessionID(track_cookie_value);
219 if (
ctx.GetSessionID() != track_cookie_value) {
221 track_cookie_value =
ctx.SetSessionID();
228 bad_tracking_cookie =
true;
231 if( !bad_tracking_cookie && !TCGI_DisableTrackingCookie::GetDefault() ) {
234 TCGI_TrackingCookieDomain::GetDefault(),
235 TCGI_TrackingCookiePath::GetDefault());
279 ERR_POST_X(12,
"CCgiContext::GetServerContext: no server context set");
280 throw runtime_error(
"no server context set");
292 pair<TCgiEntriesCI, TCgiEntriesCI>
range =
300 return s_EmptyCgiEntry.
Get();
310 "duplicate entries in request with name: " +
311 name +
": " +
value.GetValue() +
"!=" +
312 range.first->second.GetValue());
351 if ( !caf_url.empty() ) {
363 const string& x_fwd_host =
366 const string& host_port = !x_fwd_host.empty() ? x_fwd_host
370 bool no_host =
false, no_port =
false;
371 if ( !host_port.empty() ) {
372 size_t pos = host_port.
find(
':');
373 host =
CTempString(host_port, 0, pos !=
NPOS ? pos : host_port.size());
376 }
else if ( !caf_url.empty() ) {
377 no_host = no_port =
true;
397 if ( !caf_url.empty() ) {
401 if ( path.empty() ) {
405 size_t pos = path.find_first_of(
"?#");
430 const string& x_fwd_proto
432 if ( !x_fwd_proto.empty() ) {
442 (
GetRequest().GetRandomProperty(
"HTTPS",
false),
"on")
452 #if defined(NCBI_OS_UNIX)
456 # if defined(HAVE_POLL_H) && \
457 !defined(NCBI_OS_DARWIN) && !defined(NCBI_OS_CYGWIN)
458 if (
max(ifd, ofd) >= 0) {
464 if (::
poll(pfd, 2, tmo) > 0) {
472 fd_set readfds, *rfds = 0, writefds, *wfds = 0;
489 struct timeval tv, *tvp = 0;
492 ::memset(tvp, 0,
sizeof(*tvp));
494 unsigned int sec, usec;
495 timeout.
Get(&sec, &usec);
500 if (::select(nfds, rfds, wfds,
NULL, tvp) > 0) {
501 if (rfds && FD_ISSET(ifd, rfds))
503 if (wfds && FD_ISSET(ofd, wfds))
530 const string& cookie_name,
string& tid)
539 const string& entry_name,
string& tid)
541 bool is_found =
false;
551 NCBI_CGI_DISCARD_UNK_SESSION);
556 if (tid.empty())
return false;
557 if (TParamDiscardUnkSession::GetDefault())
558 return tid !=
"UNK_SESSION";
565 static const char* cookie_or_entry_name_1 =
"WebCubbyUser";
566 static const char* cookie_or_entry_name_2 =
"WebEnv";
574 bool is_found =
false;
576 &
m_Request->GetEntry(TCGI_TrackingCookieName::GetDefault(), &is_found);
598 string tag_name = TCGI_TrackingTagName::GetDefault();
601 m_Request->GetRandomProperty(tag_name,
true));
692 TCORS_JQuery_Callback_Enable;
700 TCORS_JQuery_Callback_Prefix;
713 " Accept Accept-Language Content-Language Content-Type";
715 " Origin Cache-Control Expires Last-Modified Pragma X-Accept-Charset X-Accept"
716 " X-Requested-With NCBI-SID NCBI-PHID";
738 const string& allowed = TCORS_AllowOrigin::GetDefault();
739 if ( allowed.empty() ) {
763 if ( method.empty() ) {
767 NStr::Split(TCORS_AllowMethods::GetDefault(),
", ", methods,
771 if (*it == method)
return true;
794 if ( headers.empty() ) {
800 string ah = TCORS_AllowHeaders::GetDefault();
804 if (TParamValidateCSRFToken::GetDefault()) {
819 TStringList::const_iterator ait = allowed.begin();
820 TStringList::const_iterator rit = requested.begin();
821 while (ait != allowed.end() && rit != requested.end()) {
828 return rit == requested.end();
834 string http_name(name);
845 if ( !TCORS_Enable::GetDefault() ) {
855 string jquery_callback = request.
GetEntry(
"callback");
856 if (TCORS_JQuery_Callback_Enable::GetDefault()
860 && !jquery_callback.empty()) {
861 string prefix = TCORS_JQuery_Callback_Prefix::GetDefault();
899 if ( TCORS_AllowCredentials::GetDefault() ) {
902 const string& allow_methods = TCORS_AllowMethods::GetDefault();
903 if ( !allow_methods.empty() ) {
906 string allow_headers = TCORS_AllowHeaders::GetDefault();
908 if ( !allow_headers.empty() ) {
913 allow_headers =
NStr::Join(allowed_list,
", ");
916 const string& max_age = TCORS_MaxAge::GetDefault();
917 if ( !max_age.empty() ) {
930 if ( TCORS_AllowCredentials::GetDefault() ) {
933 string exp_headers = TCORS_ExposeHeaders::GetDefault();
934 if ( !exp_headers.empty() ) {
API to store CGI session data between Web requests.
static const char * kCSRFTokenHeader
static const char * kAC_RequestMethod
string s_HeaderToHttp(const char *name)
static const char * kAC_Origin
static const char * kAC_AllowOrigin
static bool s_IsTID(const string &tid)
static bool s_IsAllowedOrigin(const string &origin)
list< string > TStringList
NCBI_PARAM_DECL(bool, CGI, Discard_UNK_SESSION)
static const char * kAC_ExposeHeaders
NCBI_PARAM_DEF_EX(bool, CGI, Discard_UNK_SESSION, false, eParam_NoThread, NCBI_CGI_DISCARD_UNK_SESSION)
static const char * kAC_MaxAge
static const char * kAC_AllowHeaders
static bool s_CheckCookieForTID(const CCgiCookies &cookies, const string &cookie_name, string &tid)
static const char * kAC_AllowCredentials
static const char * kAC_RequestHeaders
static const char * kAC_AllowMethods
static bool s_CheckValueForTID(const string &value, string &tid)
static const char * kDefaultHeaders
static bool s_IsAllowedMethod(const string &method)
typedef NCBI_PARAM_TYPE(CGI, Discard_UNK_SESSION) TParamDiscardUnkSession
static const char * kSimpleHeaders
static bool s_CheckRequestEntryForTID(const CCgiRequest *request, const string &entry_name, string &tid)
static bool s_IsAllowedHeaderList(const string &headers)
T & Get(void)
Create the variable if not created yet, return the reference.
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
CTimeout – Timeout interval.
const_iterator_pair equal_range(const key_type &key) const
iterator insert(const value_type &val)
container_type::value_type value_type
Include a standard set of the NCBI C++ Toolkit most basic headers.
std::ofstream out("events_result.xml")
main entry point for tests
#define poll(fds, nfds, timeout)
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
CCgiContext(CCgiApplication &app, const CNcbiArguments *args=0, const CNcbiEnvironment *env=0, CNcbiIstream *inp=0, CNcbiOstream *out=0, int ifd=-1, int ofd=-1, size_t errbuf_size=256, CCgiRequest::TFlags flags=0)
TStreamStatus GetStreamStatus(void) const
virtual ~CCgiContext(void)
ESecureMode x_IsSecure(void) const
CCgiApplication & x_GetApp(void) const
const CCgiRequest & GetRequest(void) const
static const char * sm_nl
void RemoveRequestValues(const string &name)
const CCgiEntry & GetRequestValue(const string &name, bool *is_found=0) const
string RetrieveTrackingId() const
CCgiException::EStatusCode m_StatusCode
unique_ptr< CCgiServerContext > m_ServerContext
virtual ~CCgiServerContext(void)
CTime m_SessionCookieExpTime
string m_SessionCookieDomain
virtual ICgiSessionStorage * GetSessionStorage(CCgiSessionParameters ¶ms) const
Get instance of CGI session storage interface.
CCgiServerContext & x_GetServerContext(void) const
virtual ~CCtxMsgString(void)
void ReplaceRequestValue(const string &name, const CCgiEntry &value)
static bool ProcessCORSRequest(const CCgiRequest &request, CCgiResponse &response)
Process cross-origin resource sharing (CORS) request.
void x_SetStatus(CCgiException::EStatusCode code, const string &msg) const
const CNcbiRegistry & GetConfig(void) const
unique_ptr< CCgiRequest > m_Request
const string & GetSelfURL(void) const
Using HTTP environment variables, compose the CGI's own URL as: SCHEME://SERVER_NAME[:SERVER_PORT]/SC...
bool IsSecure(void) const
Check if the current scheme is secure (https) or not (http).
unique_ptr< CCgiSession > m_Session
void AddRequestValue(const string &name, const CCgiEntry &value)
virtual CNcbiOstream & Write(CNcbiOstream &os) const
string m_SessionCookiePath
const CNcbiResource & GetResource(void) const
Get server 'resource'. Throw exception if the resource is not set.
virtual CCgiServerContext * LoadServerContext(CCgiContext &context)
void CheckStatus(void) const
Check if the context has any pending errors, perform any required actions (e.g.
const CNcbiResource & GetResource(void) const
void x_InitSession(CCgiRequest::TFlags flags, ICgiSessionStorage *session_storage=nullptr)
EStatusCode
HTTP status codes.
@ eStatusNotSet
Internal value - code not set.
void SetRequestMethod(CCgiRequest::ERequestMethod method)
Set HTTP request method.
const TCgiEntries & GetEntries(void) const
Get a set of entries(decoded) received from the client.
CCgiCookie * Find(const string &name, const string &domain, const string &path)
Return NULL if cannot find this exact cookie.
const string & GetValue(void) const
All "const string& GetXXX(...)" methods beneath return reference to "NcbiEmptyString" if the requeste...
void SetHeaderValue(const string &name, const string &value)
void x_SetSession(const CCgiSession &session)
const string & GetValue() const
Get the value as a string, (necessarily) prefetching it all if applicable; the result remains availab...
void SetStatus(unsigned int code, const string &reason=kEmptyStr)
void SetTrackingCookie(const string &name, const string &value, const string &domain, const string &path, const CTime &exp_time=CTime())
void SetCgiRequest(const CCgiRequest &request)
const string & GetProperty(ECgiProp prop) const
Get value of a "standard" property (return empty string if not defined)
const CCgiCookies & Cookies(void) const
const string & GetRandomProperty(const string &key, bool http=true) const
Get value of a random client property; if "http" is TRUE then add prefix "HTTP_" to the property name...
CNcbiOstream & WriteHeader(void) const
Write HTTP response header to the output stream.
void RemoveHeaderValue(const string &name)
const CCgiEntry & GetEntry(const string &name, bool *is_found=0) const
Get entry value by name.
ERequestMethod
Standard request methods.
int TFlags
Startup initialization.
void SetSecure(bool secure)
Set secure connection flag.
int GetOutputFD(void) const
Get file descriptor of the output stream (-1 if not applicable)
ERequestMethod GetRequestMethod(void) const
Get request method.
void DisableTrackingCookie(void)
@ fDisableTrackingCookie
Do not set outgoing tracking cookie.
@ fSkipDiagProperties
Set client-ip and session-id properties for logging.
@ eMethod_Other
Unknown method, use GetRequestMethodName to read.
@ eUseCookie
A session cookie will be added to the response.
@ eNoCookie
A session cookie will not be added to the response.
CDiagContext & GetDiagContext(void)
Get diag context instance.
string GetSessionID(void) const
Session ID.
void SetSessionID(const string &session)
static string SelectLastSessionID(const string &session_ids)
Select the last session id from the list of ids separated with commas and optional spaces,...
bool IsSetSessionID(void) const
static CRequestContext & GetRequestContext(void)
Shortcut to CDiagContextThreadData::GetThreadData().GetRequestContext()
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
#define NCBI_EXCEPTION_VAR(name, exception_class, err_code, message)
Create an instance of the exception to be thrown later.
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
#define NCBI_EXCEPTION_THROW(exception_var)
Throw an existing exception object.
#define THROW1_TRACE(exception_class, exception_arg)
Throw trace.
@ eParam_NoThread
Do not use per-thread values.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
static string Join(const TContainer &arr, const CTempString &delim)
Join strings using the specified delimiter.
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
void clear(void)
Clears the string.
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
size_type find(const CTempString match, size_type pos=0) const
Find the first instance of the entire matching string within the current string, beginning at an opti...
static bool Equal(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2, ECase use_case=eCase)
Test for equality of a substring with another string.
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
static string & ToUpper(string &str)
Convert string to upper case – string& version.
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
@ eNocase
Case insensitive compare.
@ eCase
Case sensitive compare.
unsigned long GetAsMilliSeconds(void) const
Get as number of milliseconds.
void Get(unsigned int *sec, unsigned int *microsec) const
Get timeout in seconds and microseconds.
bool IsFinite() const
Check if timeout holds a numeric value.
const CUrlArgs & GetArgs(void) const
Get const list of arguments.
void SetPath(const string &value)
void SetFragment(const string &value)
void clear(void)
Clear the list.
const string & GetPath(void) const
const string & GetPort(void) const
const string & GetScheme(void) const
void SetPort(const string &value)
void SetUrl(const string &url, const IUrlEncoder *encoder=0)
Parse the URL.
void SetHost(const string &value)
void SetIsGeneric(bool value)
void SetScheme(const string &value)
string ComposeUrl(CUrlArgs::EAmpEncoding amp_enc, const IUrlEncoder *encoder=0) const
Compose the URL.
@ eAmp_Char
Use & to separate arguments.
unsigned int
A callback function used to compare two keys in a database.
Definition of all error codes used in cgi (xcgi.lib).
range(_Ty, _Ty) -> range< _Ty >
const GenericPointer< typename T::ValueType > T2 value
Static variables safety - create on demand, destroy on application termination.
Defines NCBI C++ diagnostic APIs, classes, and macros.
Process information in the NCBI Registry, including working with configuration files.
static const GLdouble origin[]
Defines CRequestContext class for NCBI C++ diagnostic API.
static SLJIT_INLINE sljit_ins msg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
static CS_CONTEXT * context