1 --- a/make/rules_COMMON.mk Sun Jan 18 01:43:32 2009 -0800
2 +++ b/make/rules_COMMON.mk Thu May 07 03:20:10 2009 -0700
3 @@ -417,7 +417,7 @@
4 ifdef SHIP_ICU_RESOURCES
5 ifndef BUILD64
6 SOMETHING_EXPORTED=1
7 -_ICU_RESOURCES=$(addprefix $(OBJDIR)/, $(addsuffix _root.res, \
8 +_ICU_RESOURCES=$(addprefix $(OBJDIR)/, $(addsuffix .res, \
9 $(SHIP_ICU_RESOURCES)))
10 SHIP_RESOURCE_FILES+=$(_ICU_RESOURCES)
11 endif
12 @@ -605,6 +605,9 @@
13 ifndef NO_STD_ICU_RESOURCES_TARGET
14 compile:: $(_ICU_RESOURCES)
15 $(OBJDIR)/%_root.res: %.properties
16 + $(GENRB) -d $(OBJDIR) $<
17 +
18 +$(OBJDIR)/%.res: %.properties
19 $(GENRB) -d $(OBJDIR) $<
20 endif # NO_STD_ICU_RESOURCES_TARGET
21
1.1 --- a/schema/open-web-server_1_0.xsd Sun Jan 18 01:43:32 2009 -0800
1.2 +++ b/schema/open-web-server_1_0.xsd Thu May 07 03:20:10 2009 -0700
1.3 @@ -969,7 +969,7 @@
1.4 <xs:simpleType>
1.5 <xs:restriction base="xs:integer">
1.6 <xs:minInclusive value="1"/>
1.7 - <xs:maxInclusive value="128"/>
1.8 + <xs:maxInclusive value="256"/>
1.9 </xs:restriction>
1.10 </xs:simpleType>
1.11 </xs:element>
1.12 @@ -2380,6 +2380,17 @@
1.13 <xs:annotation>
1.14 <xs:appinfo>
1.15 <appinfo:implicit>default</appinfo:implicit>
1.16 + </xs:appinfo>
1.17 + </xs:annotation>
1.18 + </xs:element>
1.19 +
1.20 + <xs:element name="mode" type="access-logModeType" default="text" minOccurs="0" maxOccurs="1">
1.21 + <xs:annotation>
1.22 + <xs:documentation>
1.23 + If the mode element is omitted, the mode is assumed to be text.
1.24 + </xs:documentation>
1.25 + <xs:appinfo>
1.26 + <appinfo:implicit>text</appinfo:implicit>
1.27 </xs:appinfo>
1.28 </xs:annotation>
1.29 </xs:element>
1.30 @@ -3586,12 +3597,25 @@
1.31 <xs:enumeration value="Cp285"/>
1.32 <xs:enumeration value="Cp1123"/>
1.33 <xs:enumeration value="Cp1124"/>
1.34 + <xs:enumeration value="Cp858"/>
1.35 + <xs:enumeration value="Cp1140"/>
1.36 + <xs:enumeration value="Cp1141"/>
1.37 + <xs:enumeration value="Cp1142"/>
1.38 + <xs:enumeration value="Cp1143"/>
1.39 + <xs:enumeration value="Cp1144"/>
1.40 + <xs:enumeration value="Cp1145"/>
1.41 + <xs:enumeration value="Cp1146"/>
1.42 + <xs:enumeration value="Cp1147"/>
1.43 + <xs:enumeration value="Cp1148"/>
1.44 + <xs:enumeration value="Cp1149"/>
1.45 + <xs:enumeration value="Cp1047"/>
1.46 <xs:enumeration value="ISCII91"/>
1.47 <xs:enumeration value="ISO-8859-1"/>
1.48 <xs:enumeration value="ISO-8859-2"/>
1.49 <xs:enumeration value="ISO-8859-3"/>
1.50 <xs:enumeration value="ISO-8859-4"/>
1.51 <xs:enumeration value="ISO-8859-9"/>
1.52 + <xs:enumeration value="ISO-8859-11"/>
1.53 <xs:enumeration value="ISO-8859-13"/>
1.54 <xs:enumeration value="ISO-8859-15"/>
1.55 <xs:enumeration value="ISO8859_15"/>
1.56 @@ -3638,6 +3662,7 @@
1.57 <xs:enumeration value="windows-1256"/>
1.58 <xs:enumeration value="windows-1257"/>
1.59 <xs:enumeration value="windows-1250"/>
1.60 + <xs:enumeration value="windows-1251"/>
1.61 <xs:enumeration value="windows-1253"/>
1.62 <xs:enumeration value="windows-1255"/>
1.63 <xs:enumeration value="windows-1252"/>
1.64 @@ -3675,6 +3700,28 @@
1.65 <xs:enumeration value="windows-949"/>
1.66 <xs:enumeration value="windows-936"/>
1.67 <xs:enumeration value="windows-950"/>
1.68 + <xs:enumeration value="ISO-2022-CN"/>
1.69 + <xs:enumeration value="ISO-2022-JP"/>
1.70 + <xs:enumeration value="Shift_JIS"/>
1.71 + <xs:enumeration value="Cp1381"/>
1.72 + <xs:enumeration value="Cp1383"/>
1.73 + <xs:enumeration value="Cp33722"/>
1.74 + <xs:enumeration value="Cp33722"/>
1.75 + <xs:enumeration value="Cp930"/>
1.76 + <xs:enumeration value="Cp939"/>
1.77 + <xs:enumeration value="Cp942"/>
1.78 + <xs:enumeration value="Cp942C"/>
1.79 + <xs:enumeration value="Cp943"/>
1.80 + <xs:enumeration value="Cp943C"/>
1.81 + <xs:enumeration value="Cp948"/>
1.82 + <xs:enumeration value="Cp949C"/>
1.83 + <xs:enumeration value="Cp964"/>
1.84 + <xs:enumeration value="Cp970"/>
1.85 + <xs:enumeration value="JISAutoDetect"/>
1.86 + <xs:enumeration value="Johab"/>
1.87 + <xs:enumeration value="EUC-JP"/>
1.88 + <xs:enumeration value="EUC-JP-LINUX"/>
1.89 + <xs:enumeration value="EUC-JP-SOLARIS"/>
1.90 </xs:restriction>
1.91 </xs:simpleType>
1.92
1.93 @@ -4210,6 +4257,30 @@
1.94 </xs:restriction>
1.95 </xs:simpleType>
1.96
1.97 +<xs:simpleType name="access-logModeType">
1.98 + <xs:annotation>
1.99 + <xs:documentation>
1.100 + The value must be a log mode. Valid log modes are text and binary.
1.101 + </xs:documentation>
1.102 + </xs:annotation>
1.103 + <xs:restriction base="xs:token">
1.104 + <xs:enumeration value="text">
1.105 + <xs:annotation>
1.106 + <xs:documentation>
1.107 + Use text format for access log.
1.108 + </xs:documentation>
1.109 + </xs:annotation>
1.110 + </xs:enumeration>
1.111 + <xs:enumeration value="binary">
1.112 + <xs:annotation>
1.113 + <xs:documentation>
1.114 + Use binary format for access log.
1.115 + </xs:documentation>
1.116 + </xs:annotation>
1.117 + </xs:enumeration>
1.118 + </xs:restriction>
1.119 +</xs:simpleType>
1.120 +
1.121 <xs:simpleType name="sizeType">
1.122 <xs:annotation>
1.123 <xs:documentation>
2.1 --- a/src/server/Makefile Sun Jan 18 01:43:32 2009 -0800
2.2 +++ b/src/server/Makefile Thu May 07 03:20:10 2009 -0700
2.3 @@ -34,7 +34,7 @@
2.4 BUILD_ROOT=../..
2.5 include $(BUILD_ROOT)/make/defines.mk
2.6 MODULE=lib
2.7 -DIRS=httpdaemon base ldaputil frame libaccess libadmin safs libsi18n libcrypt libdrcache httpparser libsed libserverxml libproxy shtml
2.8 +DIRS=httpdaemon base ldaputil frame libaccess libadmin safs libsi18n libcrypt libdrcache httpparser libsed libserverxml libproxy shtml extras
2.9
2.10 ifdef FEAT_SEARCH
2.11 DIRS+=libnscore
3.1 --- a/src/server/base/servnss.cpp Sun Jan 18 01:43:32 2009 -0800
3.2 +++ b/src/server/base/servnss.cpp Thu May 07 03:20:10 2009 -0700
3.3 @@ -824,3 +824,73 @@
3.4
3.5 return PR_FALSE;
3.6 }
3.7 +
3.8 +/*
3.9 + * Return PR_TRUE if certa is better than certb
3.10 + */
3.11 +static PRBool is_better(CERTCertificate *certa, CERTCertificate *certb)
3.12 +{
3.13 + PRTime notBeforeA, notAfterA, notBeforeB, notAfterB;
3.14 +
3.15 + SECStatus rv = CERT_GetCertTimes(certa, ¬BeforeA, ¬AfterA);
3.16 + if (rv != SECSuccess)
3.17 + return PR_FALSE;
3.18 +
3.19 + rv = CERT_GetCertTimes(certb, ¬BeforeB, ¬AfterB);
3.20 + if (rv != SECSuccess)
3.21 + return PR_TRUE;
3.22 +
3.23 + PRBool isfutureA = (notBeforeA > PR_Now()) ? PR_TRUE : PR_FALSE;
3.24 + PRBool isfutureB = (notBeforeB > PR_Now()) ? PR_TRUE : PR_FALSE;
3.25 +
3.26 + // If one cert is newer than the other, choose that unless
3.27 + // the issue-date of newer cert is in the future and the
3.28 + // issue-date of the older cert is in the past
3.29 + if (LL_CMP(notBeforeA, >, notBeforeB)) {
3.30 + if (isfutureA && !isfutureB)
3.31 + return PR_FALSE;
3.32 + return PR_TRUE;
3.33 + } else {
3.34 + if (isfutureB && !isfutureA)
3.35 + return PR_TRUE;
3.36 + return PR_FALSE;
3.37 + }
3.38 +}
3.39 +
3.40 +NSAPI_PUBLIC CERTCertificate *servnss_get_cert_from_nickname(const char *nickname, PK11CertListType listType)
3.41 +{
3.42 + if (!nickname) { return NULL; }
3.43 +
3.44 + CERTCertificate *currentCert = NULL, // Cursor in list
3.45 + *savedCert = NULL; // Last matching cert
3.46 +
3.47 + CERTCertList* clist = PK11_ListCerts(listType, NULL);
3.48 + CERTCertListNode *cln;
3.49 + for (cln = CERT_LIST_HEAD(clist); !CERT_LIST_END(cln,clist);
3.50 + cln = CERT_LIST_NEXT(cln)) {
3.51 + currentCert = cln->cert;
3.52 + const char* cnick = (const char*) cln->appData;
3.53 + if (!cnick) {
3.54 + cnick = currentCert->nickname;
3.55 + }
3.56 + /*If nickname matches
3.57 + * Case 1: Previous match saved in savedCert?
3.58 + * if no, save currentCert into savedCert
3.59 + * Case 2: store newer cert in savedCert
3.60 + */
3.61 + if (0==strcmp(cnick, nickname))
3.62 + {
3.63 + if (savedCert == NULL || is_better(currentCert, savedCert))
3.64 + savedCert = currentCert;
3.65 + }
3.66 + }
3.67 + //We found our cert
3.68 + CERTCertificate *cert = NULL;
3.69 + if (savedCert)
3.70 + cert = CERT_DupCertificate(savedCert);
3.71 +
3.72 + CERT_DestroyCertList(clist);
3.73 +
3.74 + return cert;
3.75 +}
3.76 +
4.1 --- a/src/server/base/servnss.h Sun Jan 18 01:43:32 2009 -0800
4.2 +++ b/src/server/base/servnss.h Thu May 07 03:20:10 2009 -0700
4.3 @@ -57,4 +57,6 @@
4.4 PRBool servssl_maybe_client_hello(void *buf, int sz);
4.5 void PR_CALLBACK servssl_handshake_callback(PRFileDesc *socket, void *arg);
4.6
4.7 +NSAPI_PUBLIC CERTCertificate *servnss_get_cert_from_nickname(const char *nickname, PK11CertListType type=PK11CertListUser);
4.8 +
4.9 #endif /* SERVNSS_H */
5.1 --- a/src/server/base/sslconf.cpp Sun Jan 18 01:43:32 2009 -0800
5.2 +++ b/src/server/base/sslconf.cpp Thu May 07 03:20:10 2009 -0700
5.3 @@ -153,44 +153,6 @@
5.4 }
5.5 }
5.6
5.7 -/*
5.8 - * Attempt to find a certificate with the given nickname. If found (non-NULL
5.9 - * returned) the caller is responsible for eventually calling
5.10 - * CERT_DestroyCertificate() on it.
5.11 - *
5.12 - */
5.13 -CERTCertificate*
5.14 -SSLSocketConfiguration :: FindServerCertFromNickname(const char* name) const
5.15 -{
5.16 - if (!name) { return NULL; }
5.17 -
5.18 - CERTCertList* clist;
5.19 - clist = PK11_ListCerts(PK11CertListUser, NULL);
5.20 -
5.21 - CERTCertListNode *cln;
5.22 -
5.23 - for (cln = CERT_LIST_HEAD(clist); !CERT_LIST_END(cln,clist);
5.24 - cln = CERT_LIST_NEXT(cln))
5.25 - {
5.26 - CERTCertificate* cert = cln->cert;
5.27 - const char* nickname = (const char*) cln->appData;
5.28 - if (!nickname)
5.29 - {
5.30 - nickname = cert->nickname;
5.31 - }
5.32 - if (0==strcmp(name, nickname))
5.33 - {
5.34 - // we found our cert
5.35 - CERTCertificate* rv = CERT_DupCertificate(cert);
5.36 - CERT_DestroyCertList(clist);
5.37 - return rv;
5.38 - }
5.39 - }
5.40 - CERT_DestroyCertList(clist);
5.41 - return NULL;
5.42 -}
5.43 -
5.44 -
5.45 /*
5.46 * This function loops through all the server cert nicknames listed in the
5.47 * given config and attempts to locate each one along with associated info
5.48 @@ -252,7 +214,7 @@
5.49 ereport(LOG_VERBOSE, "Processing server cert nicknamed [%s]",
5.50 servercertNickname[i]);
5.51
5.52 - servercert[i] = FindServerCertFromNickname(servercertNickname[i]);
5.53 + servercert[i] = servnss_get_cert_from_nickname(servercertNickname[i]);
5.54
5.55 if (NULL == servercert[i])
5.56 {
6.1 --- a/src/server/base/sslconf.h Sun Jan 18 01:43:32 2009 -0800
6.2 +++ b/src/server/base/sslconf.h Thu May 07 03:20:10 2009 -0700
6.3 @@ -133,7 +133,6 @@
6.4 void set_cipher(PRInt32 cipher, const char *cipherName,
6.5 const ServerXMLSchema::Bool& on);
6.6 void set_ciphers();
6.7 - CERTCertificate* FindServerCertFromNickname(const char* name) const;
6.8 PRBool check_bypass() const;
6.9 };
6.10
7.1 --- a/src/server/base/vs.cpp Sun Jan 18 01:43:32 2009 -0800
7.2 +++ b/src/server/base/vs.cpp Thu May 07 03:20:10 2009 -0700
7.3 @@ -320,6 +320,8 @@
7.4 inline PRBool isValid() { return sn && rq && objset; }
7.5
7.6 HttpRequest* hrq;
7.7 + const VirtualServer* threadVS;
7.8 + HttpRequest* threadHrq;
7.9 pool_handle_t* poolCaller;
7.10 Session* sn;
7.11 Request* rq;
7.12 @@ -344,6 +346,8 @@
7.13 hrq = HttpRequest::CurrentRequest();
7.14 if (hrq)
7.15 HttpRequest::SetCurrentRequest(NULL);
7.16 + else
7.17 + conf_get_thread_globals(threadHrq, threadVS);
7.18
7.19 // Remember the caller's MALLOC pool
7.20 if (keyPool == -1)
7.21 @@ -400,6 +404,9 @@
7.22 if (hrq) {
7.23 HttpRequest::SetCurrentRequest(hrq);
7.24 conf_set_thread_globals(hrq);
7.25 + }
7.26 + else {
7.27 + conf_set_thread_globals(threadHrq, threadVS);
7.28 }
7.29 }
7.30
8.1 --- a/src/server/frame/conf.cpp Sun Jan 18 01:43:32 2009 -0800
8.2 +++ b/src/server/frame/conf.cpp Thu May 07 03:20:10 2009 -0700
8.3 @@ -186,6 +186,23 @@
8.4 }
8.5 }
8.6
8.7 +/* ----------------------- conf_get_thread_globals ------------------------ */
8.8 +
8.9 +/* Take a backup of thread local data.
8.10 + *
8.11 + */
8.12 +
8.13 +NSAPI_PUBLIC void conf_get_thread_globals(HttpRequest *&hrq,
8.14 + const VirtualServer *&vs)
8.15 +{
8.16 + ThreadGlobalsData *data = get_thread_globals_data();
8.17 + PR_ASSERT(data);
8.18 + if (data) {
8.19 + hrq = data->hrq;
8.20 + vs = data->vs;
8.21 + }
8.22 +
8.23 +}
8.24
8.25 /* ----------------------- conf_set_thread_globals ------------------------ */
8.26
8.27 @@ -204,6 +221,26 @@
8.28 data->initialized = PR_FALSE;
8.29 }
8.30 }
8.31 +
8.32 +
8.33 + /* ---------------------- conf_set_thread_globals ---------------------- */
8.34 +
8.35 +/* This is called to cover the scenario's when hrq could be null. The backup
8.36 + * thread local variables are set back if hrq is null.
8.37 + */
8.38 +
8.39 +NSAPI_PUBLIC void conf_set_thread_globals(class HttpRequest *hrq,
8.40 + const VirtualServer *vs)
8.41 +{
8.42 + ThreadGlobalsData *data = get_thread_globals_data();
8.43 + PR_ASSERT(data);
8.44 + if (data) {
8.45 + data->hrq = hrq;
8.46 + data->vs = vs;
8.47 + }
8.48 +
8.49 +}
8.50 +
8.51
8.52
8.53 /* ---------------------- conf_set_thread_vs_globals ---------------------- */
9.1 --- a/src/server/frame/conf.h Sun Jan 18 01:43:32 2009 -0800
9.2 +++ b/src/server/frame/conf.h Thu May 07 03:20:10 2009 -0700
9.3 @@ -83,8 +83,10 @@
9.4
9.5 NSAPI_PUBLIC conf_global_vars_s *conf_get_true_globals();
9.6 NSAPI_PUBLIC void conf_set_thread_globals(class HttpRequest *hrq);
9.7 +NSAPI_PUBLIC void conf_set_thread_globals(class HttpRequest *hrq, const VirtualServer *vs);
9.8 NSAPI_PUBLIC void conf_set_thread_vs_globals(const VirtualServer *vs);
9.9 NSAPI_PUBLIC void conf_reset_thread_globals();
9.10 +NSAPI_PUBLIC void conf_get_thread_globals(HttpRequest *&hrq, const VirtualServer*& vs);
9.11 NSAPI_PUBLIC const VirtualServer *conf_get_vs();
9.12 NSAPI_PUBLIC PRStatus conf_parse(const char *cfn, PRBool jvm_enabled);
9.13 NSAPI_PUBLIC void conf_add_init(pblock *initfn, conf_global_vars_s *cg);
10.1 --- a/src/server/frame/object.cpp Sun Jan 18 01:43:32 2009 -0800
10.2 +++ b/src/server/frame/object.cpp Thu May 07 03:20:10 2009 -0700
10.3 @@ -448,7 +448,7 @@
10.4
10.5 pblock *ncp = NULL;
10.6 if (od->client.pb) {
10.7 - ncp = pbmap.lookup(od->param.pb);
10.8 + ncp = pbmap.lookup(od->client.pb);
10.9 if (!ncp)
10.10 return PR_FAILURE;
10.11 }
11.1 --- a/src/server/frame/objset.cpp Sun Jan 18 01:43:32 2009 -0800
11.2 +++ b/src/server/frame/objset.cpp Thu May 07 03:20:10 2009 -0700
11.3 @@ -783,34 +783,64 @@
11.4 }
11.5
11.6
11.7 +/* ---------------------------- open_condition ---------------------------- */
11.8 +
11.9 +static PRInt32 open_condition(PRFileDesc *f, const Condition *cond, const char *&condtag)
11.10 +{
11.11 + PRInt32 rv = 0;
11.12 +
11.13 + if (!cond->expr) {
11.14 + condtag = "Else";
11.15 + } else if (cond->follows) {
11.16 + condtag = "ElseIf";
11.17 + } else {
11.18 + condtag = "If";
11.19 + }
11.20 + char *s = expr_format(cond->expr);
11.21 + if (strchr(s, '>')) {
11.22 + PR_ASSERT(strcmp(condtag, "Else"));
11.23 + rv |= PR_fprintf(f, "<%s (%s)>\n", condtag, s);
11.24 + } else if (*s) {
11.25 + PR_ASSERT(strcmp(condtag, "Else"));
11.26 + rv |= PR_fprintf(f, "<%s %s>\n", condtag, s);
11.27 + } else {
11.28 + PR_ASSERT(!strcmp(condtag, "Else"));
11.29 + rv |= PR_fprintf(f, "<%s>\n", condtag);
11.30 + }
11.31 + FREE(s);
11.32 +
11.33 + return rv;
11.34 +}
11.35 +
11.36 +/* --------------------------- close_condition ---------------------------- */
11.37 +
11.38 +static PRInt32 close_condition(PRFileDesc *f, const char *condtag)
11.39 +{
11.40 + return PR_fprintf(f, "</%s>\n", condtag);
11.41 +}
11.42 +
11.43 +
11.44 /* --------------------------- write_directives --------------------------- */
11.45
11.46 -static PRStatus write_directives(PRFileDesc *f, const char *dc, dtable *dt, int& i, const Condition *cond)
11.47 -{
11.48 +static PRStatus write_directives(PRFileDesc *f, const char *dc, dtable *dt, int& i, Condition ** conds, int ci, int& pci){
11.49 PRInt32 rv = 0;
11.50
11.51 // Open the condition tag
11.52 const char *condtag = NULL;
11.53 + const Condition *cond = NULL;
11.54 +
11.55 + if (ci != -1)
11.56 + cond = conds[ci];
11.57 +
11.58 if (cond) {
11.59 - if (!cond->expr) {
11.60 - condtag = "Else";
11.61 - } else if (cond->follows) {
11.62 - condtag = "ElseIf";
11.63 - } else {
11.64 - condtag = "If";
11.65 + if (ci > (pci+1)) {
11.66 + for (int lv = pci + 1; lv < ci; lv++) {
11.67 + rv |= open_condition(f, conds[lv], condtag);
11.68 + rv |= close_condition(f, condtag);
11.69 + }
11.70 }
11.71 - char *s = expr_format(cond->expr);
11.72 - if (strchr(s, '>')) {
11.73 - PR_ASSERT(strcmp(condtag, "Else"));
11.74 - rv |= PR_fprintf(f, "<%s (%s)>\n", condtag, s);
11.75 - } else if (*s) {
11.76 - PR_ASSERT(strcmp(condtag, "Else"));
11.77 - rv |= PR_fprintf(f, "<%s %s>\n", condtag, s);
11.78 - } else {
11.79 - PR_ASSERT(!strcmp(condtag, "Else"));
11.80 - rv |= PR_fprintf(f, "<%s>\n", condtag);
11.81 - }
11.82 - FREE(s);
11.83 + rv |= open_condition(f, cond, condtag);
11.84 + pci = cond->i;
11.85 }
11.86
11.87 const Condition *childcond = NULL;
11.88 @@ -829,7 +859,7 @@
11.89 // Recurse for nested <ElseIf>/<Else>
11.90 if (childcond && dt->inst[i].cond->follows == childcond) {
11.91 childcond = dt->inst[i].cond;
11.92 - write_directives(f, dc, dt, i, childcond);
11.93 + write_directives(f, dc, dt, i, conds, childcond->i, pci);
11.94 continue;
11.95 }
11.96
11.97 @@ -841,7 +871,7 @@
11.98 childcond = childcond->inside;
11.99 }
11.100 if (childcond) {
11.101 - write_directives(f, dc, dt, i, childcond);
11.102 + write_directives(f, dc, dt, i, conds, childcond->i, pci);
11.103 continue;
11.104 }
11.105 }
11.106 @@ -878,7 +908,7 @@
11.107
11.108 // Close the condition tag
11.109 if (cond)
11.110 - rv |= PR_fprintf(f, "</%s>\n", condtag);
11.111 + rv |= close_condition(f, condtag);
11.112
11.113 return (rv < 0) ? PR_FAILURE : PR_SUCCESS;
11.114 }
11.115 @@ -935,7 +965,7 @@
11.116 for (int di = 0; di < os->obj[x]->nd; di++) {
11.117 const char *dc = directive_num2name(di);
11.118 dtable *dt = &os->obj[x]->dt[di];
11.119 - for (int z = 0; z < dt->ni; rv |= write_directives(f, dc, dt, z, NULL));
11.120 + for (int z = 0, pci = -1; z < dt->ni; rv |= write_directives(f, dc, dt, z, os->obj[x]->cond, -1, pci));
11.121 }
11.122
11.123 rv |= PR_fprintf(f, "</Object>\n\n");
12.1 --- a/src/server/libaccess/lasip.cpp Sun Jan 18 01:43:32 2009 -0800
12.2 +++ b/src/server/libaccess/lasip.cpp Thu May 07 03:20:10 2009 -0700
12.3 @@ -1009,18 +1009,49 @@
12.4
12.5 // Assuming its 123.456.789.012 then,
12.6 // it can be 123.* or 123.456.* or 123.456.789.*
12.7 + // or 123.*.*.* or 123.456.*.* or *.*.*.*
12.8 // we can NOT have 12* or 123.4* keeping the traditions of 6.1
12.9 + // Now calculate length after :: has been removed
12.10 int len = strlen(ip);
12.11 - if (ip[len-1]=='*' && ip[len-2] != '.') {
12.12 - ereport(LOG_VERBOSE,
12.13 - "ERROR Invalid IP Address %s. Can only have a * after a '.'.",
12.14 + int starcount = getDelimCount(ip, '*');
12.15 + PRBool validFormat = PR_TRUE;
12.16 + if (starcount > 1 && dotcount != 3)
12.17 + validFormat = PR_FALSE;
12.18 + char* ptr = strchr(ip, '*');
12.19 + if (ptr && validFormat) {
12.20 + if ((ptr != ip) && (*(ptr -1) != '.'))
12.21 + validFormat = PR_FALSE;
12.22 + else {
12.23 + // Now we can only expect ".*" combination after ptr
12.24 + ptr++;
12.25 + while (validFormat && *ptr) {
12.26 + // *ptr is not null so it is safe to read *(ptr+1)
12.27 + // we expect only .* from this point
12.28 + if (! ((*ptr == '.') && (*(ptr+1) == '*'))) {
12.29 + validFormat = PR_FALSE;
12.30 + break;
12.31 + }
12.32 + ptr += 2;
12.33 + }
12.34 + }
12.35 + }
12.36 + if (!validFormat) {
12.37 + ereport(LOG_VERBOSE,
12.38 + "ERROR Invalid IP Address %s",
12.39 ip);
12.40 return LAS_EVAL_INVALID;
12.41 }
12.42 // if dotcount == 3 need to substitute * with 0
12.43 + // 8*1 for 123.* or 8*2 for 123.45.* or 8*3 for 123.45.67.*
12.44 int wildcardPos = 8*dotcount;
12.45 + // 8*1 for 123.*.*.* or 8*2 for 123.456.*.* or 8*0 for *.*.*.*
12.46 + if (starcount > 1)
12.47 + wildcardPos = 8*(4-starcount);
12.48 if (dotcount == 3) {
12.49 - ip[len-1]='0';
12.50 + // 123.*.*.* or 123.456.*.* or 123.456.78.* or *.*.*.*
12.51 + for(int i=0; i<len;i++)
12.52 + if (ip[i] == '*')
12.53 + ip[i] = '0';
12.54 } else {
12.55 // if dotcount == 1 need to substitute * with 0.0.0(5)
12.56 // if dotcount == 2 need to substitute * with 0.0(3)
12.57 @@ -1118,13 +1149,6 @@
12.58 // ip=*
12.59 if (!strcmp(iIP,"*"))
12.60 return (PR_AF_INET + PR_AF_INET6);
12.61 - else if (iIP[0] == '*' && strlen(iIP) > 1 ) {
12.62 - // ip=*/digits or *digits
12.63 - ereport(LOG_VERBOSE,
12.64 - "ERROR Invalid IP Address %s.",
12.65 - iIP);
12.66 - return LAS_EVAL_INVALID;
12.67 - }
12.68
12.69 int hasdot =0;
12.70 if (strchr(iIP, '.'))
12.71 @@ -1145,6 +1169,13 @@
12.72
12.73 int prefix_length=-1;
12.74 if (strchr(ip, '/')) {
12.75 + if (strchr(ip, '*')) {
12.76 + // ip=*/digits
12.77 + ereport(LOG_VERBOSE,
12.78 + "ERROR Invalid IP Address %s. Can not have * and / both",
12.79 + iIP);
12.80 + return LAS_EVAL_INVALID;
12.81 + }
12.82 prefix_length = separateIpAndNetmaskPrefixLength(ip, hasdot?32:128);
12.83 if (prefix_length == LAS_EVAL_INVALID) {
12.84 return LAS_EVAL_INVALID;
13.1 --- a/src/server/libsi18n/makefile.step2 Sun Jan 18 01:43:32 2009 -0800
13.2 +++ b/src/server/libsi18n/makefile.step2 Thu May 07 03:20:10 2009 -0700
13.3 @@ -56,9 +56,9 @@
13.4 EXE1_OBJS=makstrdb
13.5 EXE1_LIBS=libdbm
13.6
13.7 +DB_LIST=$(wildcard $(PRODUCT_I18N_DB)_*.txt)
13.8 DB_FILES=$(OBJDIR)/$(PRODUCT_I18N_DB).db \
13.9 - $(addprefix $(OBJDIR)/$(PRODUCT_I18N_DB)_, $(addsuffix .db, \
13.10 - en))
13.11 + $(addprefix $(OBJDIR)/, $(DB_LIST:.txt=.db))
13.12
13.13 local_pre_publish::$(DB_FILES)
13.14 SHIP_RESOURCE_FILES=$(DB_FILES)
14.1 --- a/src/server/plugins/fastcgi/constants.h Sun Jan 18 01:43:32 2009 -0800
14.2 +++ b/src/server/plugins/fastcgi/constants.h Thu May 07 03:20:10 2009 -0700
14.3 @@ -47,10 +47,9 @@
14.4 #include "errortypes.h"
14.5
14.6 #define CGI_VERSION "CGI/1.1"
14.7 -#define MAX_CGI_SPECIFIC_VARS 8
14.8 #define MAX_CGI_SSI_VARS 7
14.9 #define MAX_CGI_CLIENT_AUTH_VARS 64
14.10 -#define MAX_EXTRA_FCGI_VARS 6
14.11 +#define MAX_EXTRA_FCGI_VARS 8
14.12
14.13 #define SERVER_PROTOCOL "HTTP/1.0"
14.14 #define IOBUFSIZE 10240
15.1 --- a/src/server/plugins/fastcgi/fcgirequest.cpp Sun Jan 18 01:43:32 2009 -0800
15.2 +++ b/src/server/plugins/fastcgi/fcgirequest.cpp Thu May 07 03:20:10 2009 -0700
15.3 @@ -52,7 +52,7 @@
15.4
15.5 //constructor
15.6 FcgiRequest::FcgiRequest(const FcgiServerConfig *config, Session *sn, Request *rq, PRUint8 role)
15.7 -: _config(config), _sn(sn), _rq(rq), fcgiRole(role) {
15.8 +: _config(config), _sn(sn), _rq(rq), fcgiRole(role), filterApp(NULL) {
15.9 _headers = pblock_dup(_rq->headers);
15.10 _hasContentLength = (pblock_find("content-length", _headers) != NULL);
15.11 _hasBody = _hasContentLength || pblock_find("transfer-encoding", _headers);
15.12 @@ -73,6 +73,7 @@
15.13
15.14 FcgiRequest::~FcgiRequest() {
15.15 pblock_free(_headers);
15.16 + FREE(filterApp);
15.17 }
15.18
15.19 void FcgiRequest::log(int degree, const char *fmt, ...) {
15.20 @@ -97,7 +98,7 @@
15.21 // Setup the environment for the FCGI program
15.22 env = http_hdrs2env(_rq->headers);
15.23 env = cgi_common_vars(_sn, _rq, env);
15.24 - env = cgi_specific_vars(args, env);
15.25 + env = cgi_specific_vars(_sn, _rq, args, env, (fcgiRole != FCGI_AUTHORIZER));
15.26 env = cgi_ssi_vars(args, env);
15.27 env = fcgiSpecificVars(env);
15.28
15.29 @@ -129,88 +130,6 @@
15.30 return env;
15.31 }
15.32
15.33 -char** FcgiRequest::cgi_specific_vars(char *args, char** env) {
15.34 - int y;
15.35 - register pblock *pb;
15.36 - char c, *t, *u;
15.37 -
15.38 - pb = _rq->reqpb;
15.39 -
15.40 - int x;
15.41 - env = util_env_create(env, MAX_CGI_SPECIFIC_VARS, &x);
15.42 - env[x++] = util_env_str(const_cast<char *> ("GATEWAY_INTERFACE"),
15.43 - const_cast<char *> (CGI_VERSION));
15.44 -
15.45 - // Added error check for missing request information.
15.46 - t = pblock_findval("protocol", pb);
15.47 - if(t == NULL) {
15.48 - log(LOG_FAILURE, "send-request", "invalid protocol variable");
15.49 - return NULL;
15.50 - }
15.51 - env[x++] = util_env_str(const_cast<char *> ("SERVER_PROTOCOL"), t);
15.52 -
15.53 - t = pblock_findval("method", pb);
15.54 - if(t == NULL) {
15.55 - log(LOG_FAILURE, "send-request", "invalid request method variable");
15.56 - return NULL;
15.57 - }
15.58 - env[x++] = util_env_str(const_cast<char *> ("REQUEST_METHOD"), t);
15.59 -
15.60 - t = pblock_findval("uri", pb);
15.61 -
15.62 - /* Simulate CGI URIs by truncating path info */
15.63 -
15.64 -
15.65 - if( (u = pblock_findval("path-info", _rq->vars)) ) {
15.66 - y = strlen(t) - strlen(u);
15.67 - if (y >= 0) {
15.68 - c = t[y];
15.69 - t[y] = '\0';
15.70 - }
15.71 -
15.72 - if(fcgiRole != FCGI_AUTHORIZER)
15.73 - env[x++] = util_env_str(const_cast<char *> ("SCRIPT_NAME"), t);
15.74 -
15.75 - if (y >= 0) {
15.76 - t[y] = c;
15.77 - }
15.78 -
15.79 - if(fcgiRole != FCGI_AUTHORIZER) {
15.80 - env[x++] = util_env_str(const_cast<char *> ("PATH_INFO"), u);
15.81 -
15.82 - if((t = INTservact_translate_uri2(u, _sn, _rq))) {
15.83 - env[x++] = util_env_str(const_cast<char *>("PATH_TRANSLATED"), t);
15.84 - filterApp = STRDUP(t);
15.85 - FREE(t);
15.86 - }
15.87 - }
15.88 -
15.89 - } else if(fcgiRole != FCGI_AUTHORIZER) {
15.90 - env[x++] = util_env_str(const_cast<char *> ("SCRIPT_NAME"), t);
15.91 -
15.92 - if(u = pblock_findval("path", _rq->vars)) {
15.93 - env[x++] = util_env_str(const_cast<char *> ("PATH_TRANSLATED"), u);
15.94 - filterApp = u;
15.95 - }
15.96 - }
15.97 -
15.98 - if(args)
15.99 - env[x++] = util_env_str(const_cast<char *> ("QUERY_STRING"), args);
15.100 -
15.101 - t = pblock_findval("content-length", _rq->srvhdrs);
15.102 -
15.103 - if(t) {
15.104 - int cl = atoi(t);
15.105 -
15.106 - if((cl > 0) && (fcgiRole != FCGI_AUTHORIZER))
15.107 - env[x++] = util_env_str(const_cast<char *> ("CONTENT_LENGTH"), t);
15.108 - }
15.109 -
15.110 - env[x] = NULL;
15.111 -
15.112 - return env;
15.113 -}
15.114 -
15.115 char** FcgiRequest::cgi_ssi_vars(char *args, char** env) {
15.116 pblock *param = ((NSAPIRequest *) _rq)->param;
15.117
15.118 @@ -239,9 +158,29 @@
15.119
15.120 char **FcgiRequest::fcgiSpecificVars(char **env) {
15.121 int x;
15.122 - char *auth;
15.123 -
15.124 + char *path, *auth;
15.125 +
15.126 env = util_env_create(env, MAX_EXTRA_FCGI_VARS, &x);
15.127 +
15.128 + if (fcgiRole != FCGI_AUTHORIZER) {
15.129 + // set PATH_TRANSLATED if not set by cgi_specific_vars
15.130 + if (!(path = pblock_findval("path-translated", _rq->vars)) &&
15.131 + (path = pblock_findval("path", _rq->vars))) {
15.132 + env[x++] = util_env_str(const_cast<char *> ("PATH_TRANSLATED"),
15.133 + path);
15.134 + }
15.135 + // set the CONTENT_LENGTH
15.136 + // We are setting content-length here since it is not supposed to
15.137 + // be set in the cgi_specific_vars
15.138 + char *t = pblock_findval("content-length", _rq->srvhdrs);
15.139 + if (t) {
15.140 + int cl = atoi(t);
15.141 + if (cl > 0)
15.142 + env[x++] = util_env_str(const_cast<char *> ("CONTENT_LENGTH"), t);
15.143 + }
15.144 + }
15.145 +
15.146 + // set other fastcgi specific variables
15.147 env[x++] = util_env_str(const_cast<char *>("SERVER_HOSTNAME"), conf_getglobals()->Vserver_hostname);
15.148 env[x++] = util_env_str(const_cast<char *>("SERVER_ADDR"), conf_getglobals()->Vaddr);
15.149
15.150 @@ -250,11 +189,13 @@
15.151 env[x++] = util_env_str((char *)"HTTP_AUTHORIZATION", auth);
15.152 }
15.153
15.154 - if(fcgiRole == FCGI_FILTER) {
15.155 + if (fcgiRole == FCGI_FILTER) {
15.156 + filterApp = STRDUP(path);
15.157 + // set the filter file
15.158 PRStatus status = PR_GetFileInfo(filterApp, &filterFileInfo);
15.159 if(filterFileInfo.type != PR_FILE_FILE)
15.160 log(LOG_FAILURE, "send-request", "Filter application is not a file (%s)",
15.161 - filterApp);
15.162 + path);
15.163 else {
15.164 PRTime lastMod = filterFileInfo.modifyTime;
15.165 PRUint32 dataSize = filterFileInfo.size;
15.166 @@ -277,4 +218,3 @@
15.167
15.168 return env;
15.169 }
15.170 -
16.1 --- a/src/server/plugins/fastcgi/fcgirequest.h Sun Jan 18 01:43:32 2009 -0800
16.2 +++ b/src/server/plugins/fastcgi/fcgirequest.h Thu May 07 03:20:10 2009 -0700
16.3 @@ -64,7 +64,6 @@
16.4 PRUint64 contentLength;
16.5
16.6 private:
16.7 - char **cgi_specific_vars(char *args, char** env);
16.8 char **cgi_ssi_vars(char *args, char** env);
16.9 char **fcgiSpecificVars(char **env);
16.10 char **getRemoteAppEnv(char **env);
17.1 --- a/src/server/plugins/fastcgi/fcgirole.cpp Sun Jan 18 01:43:32 2009 -0800
17.2 +++ b/src/server/plugins/fastcgi/fcgirole.cpp Thu May 07 03:20:10 2009 -0700
17.3 @@ -276,9 +276,6 @@
17.4 if (filterFd) {
17.5 system_fclose(filterFd);
17.6 filterFd = NULL;
17.7 - }
17.8 - if (filterApp) {
17.9 - FREE(filterApp);
17.10 }
17.11 }
17.12
18.1 --- a/src/server/plugins/fastcgi/nsapifastcgi.cpp Sun Jan 18 01:43:32 2009 -0800
18.2 +++ b/src/server/plugins/fastcgi/nsapifastcgi.cpp Thu May 07 03:20:10 2009 -0700
18.3 @@ -296,17 +296,6 @@
18.4 // Log build info
18.5 ereport(LOG_INFORM, GetString(DBT_build_info), PRODUCT_ID" "PRODUCT_FULL_VERSION_ID" "PLUGIN_FULL_NAME" B"BUILD_NUM);
18.6
18.7 - // We need iWS 6.0 or higher
18.8 - char *version = system_version();
18.9 - char *major = strchr(version, '/');
18.10 - if ((!strstr(version, COMPANY_SHORT_NAME) && !strstr(version, "iPlanet")) || !major || atoi(major + 1) < 6) {
18.11 - if (strstr(version, "App"))
18.12 - pblock_nvinsert("error", PRODUCT_BRAND_NAME" 6.0 or higher is required", pb);
18.13 - else
18.14 - pblock_nvinsert("error", COMPANY_SHORT_NAME"/iPlanet Web Server 6.0 or higher is required", pb);
18.15 - return REQ_ABORTED;
18.16 - }
18.17 -
18.18 if(systemTmpDir)
18.19 ereport(LOG_VERBOSE, "FastCGI plugin's temp directory is %s", systemTmpDir);
18.20
19.1 --- a/src/server/plugins/htaccess/http_access.cpp Sun Jan 18 01:43:32 2009 -0800
19.2 +++ b/src/server/plugins/htaccess/http_access.cpp Thu May 07 03:20:10 2009 -0700
19.3 @@ -258,13 +258,26 @@
19.4 pblock *pb, Session *sn, Request *rq)
19.5 {
19.6 int will_allow, need_auth, num_dirs;
19.7 - char path[MAX_STRING_LEN], d[MAX_STRING_LEN];
19.8 register int x;
19.9 + char *path,*root_dir,*full_filename;
19.10 int start=0; /* start looking for .htaccess files at ntrans-base */
19.11 int init=0; /* htaccess context allocation flag */
19.12 char *base = pblock_findval("ntrans-base", rq->vars);
19.13 htaccess_context_s * ctxt;
19.14 int rv = ACCESS_OK;
19.15 + int len=0;
19.16 +
19.17 + len = strlen(p);
19.18 +
19.19 + if ((path = (char *)MALLOC(len + 1)) == NULL) {
19.20 + log_error(LOG_FAILURE,"htaccess_evaluate_access", sn, rq, "out of memory");
19.21 + return REQ_ABORTED;
19.22 + }
19.23 + if ((root_dir = (char *)MALLOC(len + 1)) == NULL) {
19.24 + log_error(LOG_FAILURE,"htaccess_evaluate_access", sn, rq, "out of memory");
19.25 + FREE(path);
19.26 + return REQ_ABORTED;
19.27 + }
19.28
19.29 if(isdir) htaccess_strcpy_dir(path,p);
19.30 else htaccess_lim_strcpy(path,p, MAX_STRING_LEN);
19.31 @@ -275,30 +288,38 @@
19.32 will_allow = 1;
19.33 need_auth = -1;
19.34
19.35 + char *access_name = pblock_findval("filename", pb);
19.36 + if (!access_name)
19.37 + access_name = DEFAULT_ACCESS_FNAME;
19.38 +
19.39 + /* Allocate space to store "/" and null apart from htaccess file name */
19.40 + if ((full_filename = (char *)MALLOC(len + strlen(access_name) + 2)) == NULL) {
19.41 + log_error(LOG_FAILURE,"htaccess_evaluate_access", sn, rq, "out of memory");
19.42 + FREE(path);
19.43 + FREE(root_dir);
19.44 + return REQ_ABORTED;
19.45 + }
19.46 +
19.47 /* traverse the request path looking for .htaccess files */
19.48 for(x=0;x<num_dirs;x++) {
19.49 - char *access_name = pblock_findval("filename", pb);
19.50 - if (!access_name)
19.51 - access_name = DEFAULT_ACCESS_FNAME;
19.52
19.53 - htaccess_make_dirstr(path,x+1,d);
19.54 + htaccess_make_dirstr(path,x+1,root_dir);
19.55
19.56 /* start checking for files at ntrans-base */
19.57 - if ((strcmp(d, base)) == 0) start=1;
19.58 + if ((strcmp(root_dir, base)) == 0) start=1;
19.59
19.60 if (start) {
19.61 - char t[MAX_STRING_LEN];
19.62 filebuffer *f;
19.63
19.64 - htaccess_make_full_path(d, access_name, t);
19.65 + htaccess_make_full_path(root_dir, access_name, full_filename);
19.66
19.67 /* don't create a context unless there is a file to parse */
19.68 - if ((f=htaccess_cfg_open(t))) {
19.69 + if ((f=htaccess_cfg_open(full_filename))) {
19.70 if (!init) {
19.71 ctxt = _htaccess_newctxt(pb, sn, rq);
19.72 init=1;
19.73 }
19.74 - htaccess_parse_access_dir(f,-1,0,d,t,ctxt);
19.75 + htaccess_parse_access_dir(f,-1,0,root_dir,full_filename,ctxt);
19.76 htaccess_cfg_close(f);
19.77 }
19.78 }
19.79 @@ -322,6 +343,9 @@
19.80
19.81 _htaccess_freectxt(ctxt);
19.82 }
19.83 + FREE(path);
19.84 + FREE(root_dir);
19.85 + FREE(full_filename);
19.86 return rv;
19.87 }
19.88
20.1 --- a/src/server/plugins/htaccess/util.cpp Sun Jan 18 01:43:32 2009 -0800
20.2 +++ b/src/server/plugins/htaccess/util.cpp Thu May 07 03:20:10 2009 -0700
20.3 @@ -212,6 +212,8 @@
20.4 dst[x++] = '/';
20.5
20.6 for(y=0; (dst[x] = src2[y]); x++,y++);
20.7 + dst[x] = '\0';
20.8 +
20.9 }
20.10
20.11
21.1 --- a/src/server/public/nsapi.h Sun Jan 18 01:43:32 2009 -0800
21.2 +++ b/src/server/public/nsapi.h Thu May 07 03:20:10 2009 -0700
21.3 @@ -1486,6 +1486,7 @@
21.4
21.5 #if NSAPI_VERSION >= 303
21.6 typedef struct nsapi303_dispatch_s nsapi303_dispatch_t;
21.7 +struct hostent;
21.8 struct nsapi303_dispatch_s {
21.9 int (*f_dns_set_hostent)(struct hostent *he, Session *sn, Request *rq);
21.10 };
22.1 --- a/src/server/safs/Cgistub.c Sun Jan 18 01:43:32 2009 -0800
22.2 +++ b/src/server/safs/Cgistub.c Thu May 07 03:20:10 2009 -0700
22.3 @@ -56,6 +56,9 @@
22.4 #include <sys/types.h>
22.5 #include <sys/socket.h>
22.6 #include <sys/stat.h>
22.7 +#if defined(SOLARIS)
22.8 +#include <dlfcn.h> /* dlopen */
22.9 +#endif
22.10 #if !defined(LINUX)
22.11 #include <sys/stropts.h>
22.12 #endif
22.13 @@ -1494,9 +1497,25 @@
22.14 void
22.15 cleanup_environment(void)
22.16 {
22.17 + int closed = 0;
22.18 +
22.19 +#if defined(SOLARIS)
22.20 + void *handle = dlopen("libc.so", RTLD_LAZY);
22.21 + void (*closefromptr)(int) = NULL;
22.22 + if (handle) {
22.23 + closefromptr = (void (*)(int))dlsym(handle,"closefrom");
22.24 + if (closefromptr) {
22.25 + (*closefromptr)(STDERR_FILENO+1);
22.26 + closed = 1;
22.27 + }
22.28 + dlclose(handle);
22.29 + handle= NULL;
22.30 + }
22.31 +#endif
22.32 +
22.33 + if (!closed) {
22.34 int fd;
22.35 int fdlimit;
22.36 - struct sigaction sa;
22.37
22.38 /*
22.39 * first, close all our potentially nasty inherited fds
22.40 @@ -1507,6 +1526,7 @@
22.41 close( fd );
22.42 }
22.43
22.44 + }
22.45 SetupCgiStubSignalDisposition();
22.46 }
22.47
23.1 --- a/src/server/safs/Makefile.cgistub Sun Jan 18 01:43:32 2009 -0800
23.2 +++ b/src/server/safs/Makefile.cgistub Thu May 07 03:20:10 2009 -0700
23.3 @@ -40,7 +40,8 @@
23.4 endif
23.5
23.6 ifeq ($(OS_ARCH),SunOS)
23.7 -LD_LIBS += -lsocket -lnsl
23.8 +C_FLAGS += -DSOLARIS
23.9 +LD_LIBS += -lsocket -lnsl -ldl
23.10 LD_FLAGS += -norunpath
23.11 ifeq ($(BUILD_ARCH),AMD64)
23.12 C_FLAGS += -xarch=amd64
24.1 --- a/src/server/safs/cgi.cpp Sun Jan 18 01:43:32 2009 -0800
24.2 +++ b/src/server/safs/cgi.cpp Thu May 07 03:20:10 2009 -0700
24.3 @@ -200,12 +200,53 @@
24.4 return argv;
24.5 }
24.6
24.7 +//----------------------------------------------------------------------------
24.8 +// get_request_uri
24.9 +//----------------------------------------------------------------------------
24.10 +
24.11 +char* get_request_uri(Request *req)
24.12 +{
24.13 + // Extract the encoded URI from the request line if possible
24.14 + char *clf_request = pblock_findkeyval(pb_key_clf_request, req->reqpb);
24.15 + if (clf_request) {
24.16 + // Find the beginning of the method
24.17 + char *method = clf_request;
24.18 + while (*method && isspace(*method))
24.19 + method++;
24.20 +
24.21 + // Skip over the method
24.22 + char *uri = method;
24.23 + while (*uri && !isspace(*uri))
24.24 + uri++;
24.25 +
24.26 + // Find the beginning of the URI
24.27 + while (*uri && isspace(*uri))
24.28 + uri++;
24.29 +
24.30 + // Find the end of the URI
24.31 + char *end = uri;
24.32 + while (*end && !isspace(*end))
24.33 + end++;
24.34 +
24.35 + // Make a copy of the uri
24.36 + int len = end - uri;
24.37 + char* request_uri = (char*) MALLOC(len+1);
24.38 + memcpy(request_uri, uri, len);
24.39 + request_uri[len] = '\0';
24.40 +
24.41 + return request_uri;
24.42 + }
24.43 +
24.44 + // No request line.
24.45 + return NULL;
24.46 +}
24.47 +
24.48 //-----------------------------------------------------------------------------
24.49 // cgi_specific_vars
24.50 //-----------------------------------------------------------------------------
24.51
24.52 -static char** cgi_specific_vars(Session *sn, Request *rq, const char *args,
24.53 - char** env)
24.54 +char** cgi_specific_vars(Session *sn, Request *rq, const char *args,
24.55 + char** env, int scriptVars)
24.56 {
24.57 int y;
24.58 register pblock *pb;
24.59 @@ -219,7 +260,7 @@
24.60
24.61 // Added error check for missing request information.
24.62 t = pblock_findval("protocol", pb);
24.63 - if(t == NULL) {
24.64 + if (t == NULL) {
24.65 log_error(LOG_FAILURE, "cgi_specific_vars", sn, rq,
24.66 XP_GetAdminStr(DBT_cgiError21), "protocol");
24.67 return NULL;
24.68 @@ -227,41 +268,59 @@
24.69 env[x++] = util_env_str("SERVER_PROTOCOL", t);
24.70
24.71 t = pblock_findval("method", pb);
24.72 - if(t == NULL) {
24.73 + if (t == NULL) {
24.74 log_error(LOG_FAILURE, "cgi_specific_vars", sn, rq,
24.75 XP_GetAdminStr(DBT_cgiError21), "request method");
24.76 return NULL;
24.77 }
24.78 env[x++] = util_env_str("REQUEST_METHOD", t);
24.79
24.80 - t = pblock_findval("uri", pb);
24.81 + if (args)
24.82 + env[x++] = util_env_str("QUERY_STRING", args);
24.83
24.84 - /* Simulate CGI URIs by truncating path info */
24.85 - if( (u = pblock_findval("path-info", rq->vars)) ) {
24.86 - y = strlen(t) - strlen(u);
24.87 - if (y >= 0) {
24.88 - c = t[y];
24.89 - t[y] = '\0';
24.90 - }
24.91 - env[x++] = util_env_str("SCRIPT_NAME", t);
24.92 - if (y >= 0) {
24.93 - t[y] = c;
24.94 + // set REQUEST_URI
24.95 + if (rq->orig_rq) {
24.96 + t = get_request_uri(rq->orig_rq);
24.97 + } else {
24.98 + t = get_request_uri(rq);
24.99 + }
24.100 + if (t) {
24.101 + env[x++] = util_env_str("REQUEST_URI", t);
24.102 + FREE(t);
24.103 + }
24.104 +
24.105 + if (scriptVars) {
24.106 + t = pblock_findval("uri", pb);
24.107 +
24.108 + /* Simulate CGI URIs by truncating path info */
24.109 + if ((u = pblock_findval("path-info", rq->vars))) {
24.110 + y = strlen(t) - strlen(u);
24.111 + if (y >= 0) {
24.112 + c = t[y];
24.113 + t[y] = '\0';
24.114 + }
24.115 + env[x++] = util_env_str("SCRIPT_NAME", t);
24.116 + if (y >= 0) {
24.117 + t[y] = c;
24.118 + }
24.119 +
24.120 + env[x++] = util_env_str("PATH_INFO", u);
24.121 + if((t = INTservact_translate_uri2(u, sn, rq))) {
24.122 + env[x++] = util_env_str("PATH_TRANSLATED", t);
24.123 + // keep path-translated in rq->vars since we may need it
24.124 + // during fastcgi processing
24.125 + pblock_nvinsert("path-translated", t, rq->vars);
24.126 + FREE(t);
24.127 + }
24.128 + } else {
24.129 + env[x++] = util_env_str("SCRIPT_NAME", t);
24.130 }
24.131
24.132 - env[x++] = util_env_str("PATH_INFO", u);
24.133 - if((t = INTservact_translate_uri2(u, sn, rq))) {
24.134 - env[x++] = util_env_str("PATH_TRANSLATED", t);
24.135 - FREE(t);
24.136 - }
24.137 + if (t = pblock_findval("path", rq->vars))
24.138 + env[x++] = util_env_str("SCRIPT_FILENAME", t);
24.139 }
24.140 - else
24.141 - env[x++] = util_env_str("SCRIPT_NAME", t);
24.142 -
24.143 - if(args)
24.144 - env[x++] = util_env_str("QUERY_STRING", args);
24.145
24.146 env[x] = NULL;
24.147 -
24.148 return env;
24.149 }
24.150
24.151 @@ -1190,7 +1249,7 @@
24.152 char **env;
24.153 env = http_hdrs2env(rq->headers);
24.154 env = cgi_common_vars(sn, rq, env);
24.155 - env = cgi_specific_vars(sn, rq, args, env);
24.156 + env = cgi_specific_vars(sn, rq, args, env, 1); // 1 implies add all variables
24.157 if(env == NULL) {
24.158 log_error(LOG_FAILURE, "send-cgi", sn, rq,
24.159 XP_GetAdminStr(DBT_cgiError21), "cgi specific variables");
24.160 @@ -1422,3 +1481,4 @@
24.161 {
24.162 return _initenv;
24.163 }
24.164 +
25.1 --- a/src/server/safs/cgi.h Sun Jan 18 01:43:32 2009 -0800
25.2 +++ b/src/server/safs/cgi.h Thu May 07 03:20:10 2009 -0700
25.3 @@ -42,6 +42,7 @@
25.4 // cgi
25.5 const pblock* GetCgiInitEnv();
25.6 NSAPI_PUBLIC char** cgi_common_vars(Session *sn, Request *rq, char **env);
25.7 +NSAPI_PUBLIC char** cgi_specific_vars(Session *sn, Request *rq, const char *args, char **env, int scriptVars);
25.8 void cgi_add_var(const char *name, const char *value);
25.9 void cgi_set_timeout(PRIntervalTime timeout);
25.10 void cgi_set_idle_timeout(PRIntervalTime timeout);
26.1 --- a/src/server/safs/dbtsafs.h Sun Jan 18 01:43:32 2009 -0800
26.2 +++ b/src/server/safs/dbtsafs.h Thu May 07 03:20:10 2009 -0700
26.3 @@ -324,4 +324,6 @@
26.4 ResDef(DBT_MalformedPathX, 393, "CORE4393: malformed path: %s")
26.5 ResDef(DBT_pcheckError15, 394, "HTTP4394: missing parameter (need bong-file)")
26.6 ResDef(DBT_nsfcsafEreport23, 395, "HTTP4395: Failed to set the max open descriptor in file cache")
26.7 + ResDef(DBT_flexLogError4, 396, "HTTP4396: Log file %s should be removed before changing its format (ASCII <--> Binary)")
26.8 + ResDef(DBT_flexLogError5, 397, "HTTP4397: Binary log file version mismatch error. Please remove the log file and restart the server" )
26.9 END_STR(safs)
27.1 --- a/src/server/safs/dump.cpp Sun Jan 18 01:43:32 2009 -0800
27.2 +++ b/src/server/safs/dump.cpp Thu May 07 03:20:10 2009 -0700
27.3 @@ -655,7 +655,8 @@
27.4 thread->lock();
27.5
27.6 PRUint32 mode = thread->threadStats.mode;
27.7 - if (mode != STATS_THREAD_EMPTY && mode != STATS_THREAD_IDLE) {
27.8 + if (mode != STATS_THREAD_EMPTY && mode != STATS_THREAD_IDLE &&
27.9 + mode != STATS_THREAD_KEEPALIVE) {
27.10 rows[y].columns[SESSION_COLUMN_PROCESS].printf("%u", process->procStats.pid);
27.11 rows[y].columns[SESSION_COLUMN_STATUS] = StatsManager::getMode(&thread->threadStats);
27.12
28.1 --- a/src/server/safs/flexlog.cpp Sun Jan 18 01:43:32 2009 -0800
28.2 +++ b/src/server/safs/flexlog.cpp Thu May 07 03:20:10 2009 -0700
28.3 @@ -37,78 +37,24 @@
28.4 * Don Eastman, imported by Mike McCool
28.5 */
28.6
28.7 -#include "netsite.h"
28.8 -#include "support/NSString.h"
28.9 -#include "time/nstime.h"
28.10 -#include "base/util.h"
28.11 -#include "base/date.h"
28.12 #include "base/ereport.h"
28.13 #include "base/vs.h"
28.14 #include "frame/accel.h"
28.15 #include "frame/conf.h"
28.16 -#include "frame/log.h"
28.17 -#include "frame/object.h"
28.18 -#include "safs/flexlog.h"
28.19 #include "safs/dbtsafs.h"
28.20 #include "httpdaemon/vsconf.h"
28.21 #include "httpdaemon/connqueue.h"
28.22 #include "httpdaemon/httpheader.h"
28.23 #include "httpdaemon/logmanager.h"
28.24 +#include "generated/ServerXMLSchema/AccessLogMode.h"
28.25 +#include "flexlogcommon.h"
28.26
28.27 +/* Check binlog.cpp for binary mode file format */
28.28
28.29 /*
28.30 * DEFAULT_LOG_NAME is the log name used when none is explicitly specified.
28.31 */
28.32 #define DEFAULT_LOG_NAME "default"
28.33 -
28.34 -/*
28.35 - * FORMAT_PREFIX is the prefix for the format line in a log file. The format
28.36 - * line records the log format in use in that log file.
28.37 - */
28.38 -#define FORMAT_PREFIX "format="
28.39 -
28.40 -/*
28.41 - * FORMAT_PREFIX_LEN is the number of characters in FORMAT_PREFIX (not
28.42 - * including any trailing '\0).
28.43 - */
28.44 -#define FORMAT_PREFIX_LEN (sizeof(FORMAT_PREFIX) - 1)
28.45 -
28.46 -/*
28.47 - * FORMAT_LEN is the maximum length of the format string in a log file's
28.48 - * format line, not including the "format=" prefix or trailing EOL.
28.49 - */
28.50 -#define FORMAT_LEN (FORMAT_LINE_LEN - FORMAT_PREFIX_LEN - ENDLINE_LEN)
28.51 -
28.52 -/*
28.53 - * FORMAT_LINE_LEN is the maximum length of the format line in a log file,
28.54 - * including the "format=" prefix and trailing EOL.
28.55 - */
28.56 -#define FORMAT_LINE_LEN 2048
28.57 -
28.58 -/*
28.59 - * TIME_PREFIX is the prefix for the optional time line in a log file. The
28.60 - * time line records the base time from which %RELATIVETIME% values are
28.61 - * computed.
28.62 - */
28.63 -#define TIME_PREFIX "time="
28.64 -
28.65 -/*
28.66 - * TIME_PREFIX_LEN is the number of characters in TIME_PREFIX (not including
28.67 - * any trailing '\0).
28.68 - */
28.69 -#define TIME_PREFIX_LEN (sizeof(TIME_PREFIX) - 1)
28.70 -
28.71 -/*
28.72 - * TIME_LINE_LEN is the maximum length of the time line in a log file,
28.73 - * including the "time=" prefix and trailing EOL.
28.74 - */
28.75 -#define TIME_LINE_LEN (TIME_PREFIX_LEN + UTIL_I64TOA_SIZE + ENDLINE_LEN)
28.76 -
28.77 -/*
28.78 - * ENDLINE_LEN is the number of characters in an EOL (not including any
28.79 - * trailing '\0').
28.80 - */
28.81 -#define ENDLINE_LEN (sizeof(ENDLINE) - 1)
28.82
28.83 /*
28.84 * DOT_DOT_DOT_LEN is the length of the "..." suffix we attach to truncated
28.85 @@ -125,110 +71,6 @@
28.86 * TOKENS_ARRAY_INCSIZE is the allocation quantum for the tokens[] array.
28.87 */
28.88 #define TOKENS_ARRAY_INCSIZE 8
28.89 -
28.90 -/*
28.91 - * flex_scan_percent_token groks the following tokens.
28.92 - */
28.93 -#define SYSDATE "SYSDATE"
28.94 -#define LOCALEDATE "LOCALEDATE"
28.95 -#define TIME "TIME"
28.96 -#define RELATIVETIME "RELATIVETIME"
28.97 -#define SES_CLIENT_IP "Ses->client.ip"
28.98 -#define REQ_METHOD_NUM "Req->method_num"
28.99 -#define REQ_PROTV_NUM "Req->protv_num"
28.100 -#define REQ_REQPB_CLF_REQUEST "Req->reqpb.clf-request"
28.101 -#define REQ_REQPB_CLF_REQUEST_METHOD "Req->reqpb.clf-request.method"
28.102 -#define REQ_REQPB_CLF_REQUEST_URI "Req->reqpb.clf-request.uri"
28.103 -#define REQ_REQPB_CLF_REQUEST_URI_ABS_PATH "Req->reqpb.clf-request.uri.abs_path"
28.104 -#define REQ_REQPB_CLF_REQUEST_URI_QUERY "Req->reqpb.clf-request.uri.query"
28.105 -#define REQ_REQPB_CLF_REQUEST_PROTOCOL "Req->reqpb.clf-request.protocol"
28.106 -#define REQ_REQPB_CLF_REQUEST_PROTOCOL_NAME "Req->reqpb.clf-request.protocol.name"
28.107 -#define REQ_REQPB_CLF_REQUEST_PROTOCOL_VERSION "Req->reqpb.clf-request.protocol.version"
28.108 -#define REQ_REQPB_METHOD "Req->reqpb.method"
28.109 -#define REQ_SRVHDRS_CLF_STATUS "Req->srvhdrs.clf-status"
28.110 -#define REQ_SRVHDRS_STATUS_CODE "Req->srvhdrs.status.code"
28.111 -#define REQ_SRVHDRS_STATUS_REASON "Req->srvhdrs.status.reason"
28.112 -#define REQ_SRVHDRS_CONTENT_LENGTH "Req->srvhdrs.content-length"
28.113 -#define REQ_HEADERS_REFERER "Req->headers.referer"
28.114 -#define REQ_HEADERS_USER_AGENT "Req->headers.user-agent"
28.115 -#define REQ_VARS_AUTH_USER "Req->vars.auth-user"
28.116 -#define VSID "vsid"
28.117 -#define DURATION "duration"
28.118 -#define SUBSYSTEM "subsystem"
28.119 -#define REQ_HEADERS_COOKIE_PREFIX "Req->headers.cookie."
28.120 -#define REQ_HEADERS_COOKIE_PREFIX_LEN (sizeof(REQ_HEADERS_COOKIE_PREFIX) - 1)
28.121 -
28.122 -/*
28.123 - * FlexTokenType identifies the type of token that was parsed from a flex-log
28.124 - * format string.
28.125 - */
28.126 -enum FlexTokenType {
28.127 - TOKEN_TEXT_OFFSET,
28.128 - TOKEN_TEXT_POINTER,
28.129 - TOKEN_MODEL,
28.130 - TOKEN_SYSDATE,
28.131 - TOKEN_LOCALEDATE,
28.132 - TOKEN_TIME,
28.133 - TOKEN_RELATIVETIME,
28.134 - TOKEN_IP,
28.135 - TOKEN_DNS,
28.136 - TOKEN_METHOD_NUM,
28.137 - TOKEN_PROTV_NUM,
28.138 - TOKEN_REQUEST_LINE,
28.139 - TOKEN_REQUEST_LINE_URI,
28.140 - TOKEN_REQUEST_LINE_URI_ABS_PATH,
28.141 - TOKEN_REQUEST_LINE_URI_QUERY,
28.142 - TOKEN_REQUEST_LINE_PROTOCOL,
28.143 - TOKEN_REQUEST_LINE_PROTOCOL_NAME,
28.144 - TOKEN_REQUEST_LINE_PROTOCOL_VERSION,
28.145 - TOKEN_METHOD,
28.146 - TOKEN_STATUS_CODE,
28.147 - TOKEN_STATUS_REASON,
28.148 - TOKEN_CONTENT_LENGTH,
28.149 - TOKEN_REFERER,
28.150 - TOKEN_USER_AGENT,
28.151 - TOKEN_AUTH_USER,
28.152 - TOKEN_VSID,
28.153 - TOKEN_DURATION,
28.154 - TOKEN_SUBSYSTEM,
28.155 - TOKEN_COOKIE,
28.156 - TOKEN_PB_KEY,
28.157 - TOKEN_PB_NAME,
28.158 - TOKEN_SN_CLIENT_KEY,
28.159 - TOKEN_SN_CLIENT_NAME,
28.160 - TOKEN_RQ_VARS_KEY,
28.161 - TOKEN_RQ_VARS_NAME,
28.162 - TOKEN_RQ_REQPB_KEY,
28.163 - TOKEN_RQ_REQPB_NAME,
28.164 - TOKEN_RQ_HEADERS_KEY,
28.165 - TOKEN_RQ_HEADERS_NAME,
28.166 - TOKEN_RQ_SRVHDRS_KEY,
28.167 - TOKEN_RQ_SRVHDRS_NAME
28.168 -};
28.169 -
28.170 -/*
28.171 - * FlexToken describes a token that was parsed from a flex-log format string.
28.172 - */
28.173 -struct FlexToken {
28.174 - FlexTokenType type;
28.175 - char *p;
28.176 - int offset;
28.177 - int len;
28.178 - ModelString *model;
28.179 - const pb_key *key;
28.180 -};
28.181 -
28.182 -/*
28.183 - * FlexFormat defines the format of a log file.
28.184 - */
28.185 -struct FlexFormat {
28.186 - FlexFormat *next; // next FlexFormat in flex_format_list
28.187 - char *format; // flex-log format string
28.188 - FlexToken *tokens; // parsed tokens
28.189 - int ntokens; // number of elements in tokens[]
28.190 - PRBool accel; // set if tokens can be retrieved from the accelerator
28.191 - int refcount; // number of references (excluding flex_format_list's)
28.192 -};
28.193
28.194 /*
28.195 * FlexTemplate is a log file template defined by the flex-init SAF.
28.196 @@ -258,6 +100,7 @@
28.197 struct FlexFormatted {
28.198 const char *p;
28.199 int len;
28.200 + PRBool appendNull;
28.201 };
28.202
28.203 /*
28.204 @@ -350,6 +193,7 @@
28.205 case TOKEN_AUTH_USER:
28.206 case TOKEN_VSID:
28.207 case TOKEN_SUBSYSTEM:
28.208 + case TOKEN_RECORD_SIZE:
28.209 return PR_TRUE;
28.210
28.211 default:
28.212 @@ -453,7 +297,8 @@
28.213
28.214 /* ----------------------- flex_scan_percent_token ------------------------ */
28.215
28.216 -static const char *flex_scan_percent_token(FlexFormat *f, const char *p)
28.217 +extern "C" NSAPI_PUBLIC
28.218 +const char *flex_scan_percent_token(FlexFormat *f, const char *p)
28.219 {
28.220 PR_ASSERT(*p == '%');
28.221
28.222 @@ -541,7 +386,8 @@
28.223
28.224 /* ------------------------ flex_scan_dollar_token ------------------------ */
28.225
28.226 -static const char *flex_scan_dollar_token(FlexFormat *f, const char *p)
28.227 +extern "C" NSAPI_PUBLIC
28.228 +const char *flex_scan_dollar_token(FlexFormat *f, const char *p)
28.229 {
28.230 PR_ASSERT(*p == '$');
28.231
28.232 @@ -568,7 +414,8 @@
28.233
28.234 /* ------------------------- flex_scan_text_token ------------------------- */
28.235
28.236 -static const char *flex_scan_text_token(FlexFormat *f, const char *p)
28.237 +extern "C" NSAPI_PUBLIC
28.238 +const char *flex_scan_text_token(FlexFormat *f, const char *p)
28.239 {
28.240 NSString text;
28.241
28.242 @@ -590,7 +437,8 @@
28.243
28.244 /* ------------------------- flex_acquire_format -------------------------- */
28.245
28.246 -static FlexFormat *flex_acquire_format(const char *format)
28.247 +static FlexFormat *flex_acquire_format(const char *format,
28.248 + PRBool binary = PR_FALSE)
28.249 {
28.250 PR_Lock(flex_format_lock);
28.251
28.252 @@ -613,6 +461,10 @@
28.253 f->ntokens = 0;
28.254 f->accel = PR_TRUE;
28.255 f->refcount = 1; // reference for caller
28.256 +
28.257 + // In binary log first write record length and then the line
28.258 + if (binary)
28.259 + flex_add_token(f, TOKEN_RECORD_SIZE);
28.260
28.261 // Parse the format string into tokens
28.262 const char *p = f->format;
28.263 @@ -791,6 +643,20 @@
28.264 return protocol;
28.265 }
28.266
28.267 +/* -------------------------- flex_format_binary -------------------------- */
28.268 +/* T can be anything like short or PRInt64 */
28.269 +template <class T>
28.270 +static inline int flex_format_binary(pool_handle_t *pool, T i, const char **p)
28.271 +{
28.272 + int len = sizeof(T);
28.273 + char *buf = (char *)pool_malloc(pool, len);
28.274 + if (!buf)
28.275 + return -1;
28.276 +
28.277 + memcpy((void *)buf, &i, len);
28.278 + *p = buf;
28.279 + return len;
28.280 +}
28.281
28.282 /* --------------------------- flex_format_date --------------------------- */
28.283
28.284 @@ -810,10 +676,42 @@
28.285 return -1;
28.286 }
28.287
28.288 +/* --------------------------- flex_format_time --------------------------- */
28.289 +
28.290 +extern "C" NSAPI_PUBLIC
28.291 +int flex_format_time(pool_handle_t *pool, time_t tim, int type, const char **p)
28.292 +{
28.293 + const int size = 64; // big enough for CLF or any "reasonable" locale
28.294 + char *buf = (char *) pool_malloc(pool, size);
28.295 + if (!buf)
28.296 + return -1;
28.297 +
28.298 + int len = 0;
28.299 + switch(type) {
28.300 + case TOKEN_SYSDATE :
28.301 + len = date_format_time(tim, date_format_clf, buf, size);
28.302 + break;
28.303 + case TOKEN_LOCALEDATE :
28.304 + len = date_format_time(tim, date_format_locale, buf, size);
28.305 + break;
28.306 + default :
28.307 + break;
28.308 + }
28.309 +
28.310 + if (len <= 0) {
28.311 + pool_free(pool, (void *)buf);
28.312 + buf = NULL;
28.313 + }
28.314 +
28.315 + *p = buf;
28.316 + return len;
28.317 +}
28.318 +
28.319
28.320 /* ---------------------------- flex_format_64 ---------------------------- */
28.321
28.322 -static inline int flex_format_64(pool_handle_t *pool, PRInt64 v, const char **p)
28.323 +extern "C" NSAPI_PUBLIC
28.324 +int flex_format_64(pool_handle_t *pool, PRInt64 v, const char **p)
28.325 {
28.326 char *buf = (char *) pool_malloc(pool, UTIL_I64TOA_SIZE);
28.327 if (!buf)
28.328 @@ -922,13 +820,14 @@
28.329
28.330 /* ------------------------- flex_format_duration ------------------------- */
28.331
28.332 -static inline int flex_format_duration(Session *sn, Request *rq, const char **p)
28.333 +static inline int flex_format_duration(Session *sn, Request *rq,
28.334 + const char **p, PRBool binary)
28.335 {
28.336 PRIntervalTime start_ticks;
28.337 if (request_get_start_interval(rq, &start_ticks) != PR_SUCCESS)
28.338 return -1;
28.339
28.340 - const int size = 15; // big enough for a year
28.341 + const int size = binary ? sizeof(PRUint64) : 15; // big enough for a year
28.342 char *buf = (char *) pool_malloc(sn->pool, size);
28.343 if (!buf)
28.344 return -1;
28.345 @@ -939,6 +838,11 @@
28.346 int elapsed_s = ft_time() - rq->req_start;
28.347 if (elapsed_s > flex_max_seconds / 2) {
28.348 // Format duration as s*1000000 to avoid PRIntervalTime overflow
28.349 + if (binary) {
28.350 + PRUint64 t = elapsed_s*1000000;
28.351 + memcpy(buf, &t, size);
28.352 + return size;
28.353 + }
28.354 return PR_snprintf(buf, size, "%d000000", elapsed_s);
28.355 }
28.356 }
28.357 @@ -946,6 +850,10 @@
28.358 PRUint64 elapsed_ticks = PR_IntervalNow() - start_ticks;
28.359 PRUint64 elapsed_us = elapsed_ticks * flex_us_per_tick;
28.360
28.361 + if (binary) {
28.362 + memcpy(buf, &elapsed_us, size);
28.363 + return size;
28.364 + }
28.365 return PR_snprintf(buf, size, "%llu", elapsed_us);
28.366 }
28.367
28.368 @@ -992,6 +900,7 @@
28.369 {
28.370 const FlexFormat *f = log->format;
28.371 int pos = 0;
28.372 + int nullCount = 0;
28.373
28.374 // Format tokens for a request served by NSAPI
28.375 for (int ti = 0; ti < f->ntokens; ti++) {
28.376 @@ -999,11 +908,17 @@
28.377
28.378 const char *p = NULL;
28.379 int len = -1;
28.380 + formatted[ti].appendNull = PR_FALSE;
28.381
28.382 switch (t->type) {
28.383 case TOKEN_TEXT_OFFSET:
28.384 p = f->format + t->offset;
28.385 - len = t->len;
28.386 + // not writing beautification stuff in binary log
28.387 + if (f->binary) {
28.388 + len = 0;
28.389 + } else {
28.390 + len = t->len;
28.391 + }
28.392 break;
28.393
28.394 case TOKEN_TEXT_POINTER:
28.395 @@ -1014,22 +929,43 @@
28.396 case TOKEN_MODEL:
28.397 if (model_str_interpolate(t->model, sn, rq, &p, &len))
28.398 log_error(LOG_VERBOSE, "flex-log", sn, rq, "error interpolating format (%s)", system_errmsg());
28.399 + else if (f->binary && p && (len > 0)) { // for '\0'
28.400 + formatted[ti].appendNull = PR_TRUE;
28.401 + nullCount++;
28.402 + }
28.403 break;
28.404
28.405 case TOKEN_SYSDATE:
28.406 - len = flex_format_date(sn->pool, date_format_clf, &p);
28.407 + if (f->binary)
28.408 + len = flex_format_binary <PRInt64> (sn->pool, (PRInt64)
28.409 + ft_time(), &p);
28.410 + else
28.411 + len = flex_format_date(sn->pool, date_format_clf, &p);
28.412 break;
28.413
28.414 case TOKEN_LOCALEDATE:
28.415 - len = flex_format_date(sn->pool, date_format_locale, &p);
28.416 + if (f->binary)
28.417 + len = flex_format_binary <PRInt64> (sn->pool, (PRInt64)
28.418 + ft_time(), &p);
28.419 + else
28.420 + len = flex_format_date(sn->pool, date_format_locale, &p);
28.421 break;
28.422
28.423 case TOKEN_TIME:
28.424 - len = flex_format_64(sn->pool, ft_time(), &p);
28.425 + if (f->binary)
28.426 + len = flex_format_binary <PRInt64> (sn->pool, (PRInt64)
28.427 + ft_time(), &p);
28.428 + else
28.429 + len = flex_format_64(sn->pool, ft_time(), &p);
28.430 break;
28.431
28.432 case TOKEN_RELATIVETIME:
28.433 - len = flex_format_64(sn->pool, (PRInt64) ft_time() - log->epoch, &p);
28.434 + if (f->binary)
28.435 + len = flex_format_binary <PRInt64> (sn->pool, (PRInt64)
28.436 + (ft_time() - log->epoch), &p);
28.437 + else
28.438 + len = flex_format_64(sn->pool, (PRInt64) ft_time()
28.439 + - log->epoch, &p);
28.440 break;
28.441
28.442 case TOKEN_IP:
28.443 @@ -1044,11 +980,19 @@
28.444 break;
28.445
28.446 case TOKEN_METHOD_NUM:
28.447 - len = flex_format_method_num(sn->pool, rq->method_num, &p);
28.448 + if (f->binary)
28.449 + len = flex_format_binary <short> (sn->pool, (short)
28.450 + rq->method_num, &p);
28.451 + else
28.452 + len = flex_format_method_num(sn->pool, rq->method_num, &p);
28.453 break;
28.454
28.455 case TOKEN_PROTV_NUM:
28.456 - len = flex_format_protv_num(sn->pool, rq->protv_num, &p);
28.457 + if (f->binary)
28.458 + len = flex_format_binary <short>(sn->pool, (short)
28.459 + rq->protv_num, &p);
28.460 + else
28.461 + len = flex_format_protv_num(sn->pool, rq->protv_num, &p);
28.462 break;
28.463
28.464 case TOKEN_REQUEST_LINE:
28.465 @@ -1060,6 +1004,10 @@
28.466 p = flex_skip_method(p);
28.467 if (p)
28.468 for (len = 0; p[len] && !isspace(p[len]); len++);
28.469 + if (f->binary && p && (len > 0)) { // for '\0'
28.470 + formatted[ti].appendNull = PR_TRUE;
28.471 + nullCount++;
28.472 + }
28.473 break;
28.474
28.475 case TOKEN_REQUEST_LINE_URI_ABS_PATH:
28.476 @@ -1067,6 +1015,10 @@
28.477 p = flex_skip_method(p);
28.478 if (p)
28.479 for (len = 0; p[len] && p[len] != '?' && !isspace(p[len]); len++);
28.480 + if (f->binary && p && (len > 0)) { // for '\0'
28.481 + formatted[ti].appendNull = PR_TRUE;
28.482 + nullCount++;
28.483 + }
28.484 break;
28.485
28.486 case TOKEN_REQUEST_LINE_URI_QUERY:
28.487 @@ -1074,6 +1026,10 @@
28.488 p = flex_skip_prefix(p, '?');
28.489 if (p)
28.490 for (len = 0; p[len] && !isspace(p[len]); len++);
28.491 + if (f->binary && p && (len > 0)) { // for '\0'
28.492 + formatted[ti].appendNull = PR_TRUE;
28.493 + nullCount++;
28.494 + }
28.495 break;
28.496
28.497 case TOKEN_REQUEST_LINE_PROTOCOL:
28.498 @@ -1084,6 +1040,10 @@
28.499 p = flex_get_request_line_protocol(rq);
28.500 if (p)
28.501 for (len = 0; p[len] && p[len] != '/'; len++);
28.502 + if (f->binary && p && (len > 0)) { // for '\0'
28.503 + formatted[ti].appendNull = PR_TRUE;
28.504 + nullCount++;
28.505 + }
28.506 break;
28.507
28.508 case TOKEN_REQUEST_LINE_PROTOCOL_VERSION:
28.509 @@ -1097,8 +1057,14 @@
28.510
28.511 case TOKEN_STATUS_CODE:
28.512 p = pblock_findkeyval(pb_key_status, rq->srvhdrs);
28.513 - if (p && p[0] && p[1] && p[2])
28.514 - len = 3;
28.515 + if (p && p[0] && p[1] && p[2]) {
28.516 + if (f->binary) {
28.517 + short s = atoi(p);
28.518 + len = flex_format_binary <short> (sn->pool, s, &p);
28.519 + } else {
28.520 + len = 3;
28.521 + }
28.522 + }
28.523 break;
28.524
28.525 case TOKEN_STATUS_REASON:
28.526 @@ -1112,6 +1078,10 @@
28.527
28.528 case TOKEN_CONTENT_LENGTH:
28.529 p = pblock_findkeyval(pb_key_content_length, rq->srvhdrs);
28.530 + if (f->binary && p) {
28.531 + PRInt64 cl = util_atoi64(p);
28.532 + len = flex_format_binary <PRInt64> (sn->pool, cl, &p);
28.533 + }
28.534 break;
28.535
28.536 case TOKEN_REFERER:
28.537 @@ -1131,16 +1101,24 @@
28.538 break;
28.539
28.540 case TOKEN_DURATION:
28.541 - len = flex_format_duration(sn, rq, &p);
28.542 + len = flex_format_duration(sn, rq, &p, f->binary);
28.543 break;
28.544
28.545 case TOKEN_SUBSYSTEM:
28.546 p = "NSAPI";
28.547 len = 5;
28.548 + if (f->binary) { // for '\0'
28.549 + formatted[ti].appendNull = PR_TRUE;
28.550 + nullCount++;
28.551 + }
28.552 break;
28.553
28.554 case TOKEN_COOKIE:
28.555 len = flex_format_cookie(sn, rq, t->p, &p);
28.556 + if (f->binary && p && (len > 0)) { // for '\0'
28.557 + formatted[ti].appendNull = PR_TRUE;
28.558 + nullCount++;
28.559 + }
28.560 break;
28.561
28.562 case TOKEN_PB_KEY:
28.563 @@ -1190,6 +1168,11 @@
28.564 case TOKEN_RQ_SRVHDRS_NAME:
28.565 p = pblock_findval(t->p, rq->srvhdrs);
28.566 break;
28.567 + case TOKEN_RECORD_SIZE:
28.568 + // Field to add buffer length
28.569 + len = sizeof(PRInt32);
28.570 + p = (char *)pool_malloc(sn->pool, len);
28.571 + break;
28.572
28.573 default:
28.574 PR_ASSERT(0);
28.575 @@ -1197,11 +1180,22 @@
28.576 }
28.577
28.578 if (p) {
28.579 - if (len == -1)
28.580 + if (len == -1) {
28.581 len = strlen(p);
28.582 + if (f->binary) { // for '\0'
28.583 + formatted[ti].appendNull = PR_TRUE;
28.584 + nullCount++;
28.585 + }
28.586 + }
28.587 } else {
28.588 - p = "-";
28.589 - len = 1;
28.590 + if (f->binary) { // for '\0'
28.591 + len = 0;
28.592 + formatted[ti].appendNull = PR_TRUE;
28.593 + nullCount++;
28.594 + } else {
28.595 + p = "-";
28.596 + len = 1;
28.597 + }
28.598 }
28.599
28.600 formatted[ti].p = p;
28.601 @@ -1210,6 +1204,11 @@
28.602 pos += len;
28.603 }
28.604
28.605 + pos += nullCount;
28.606 + // We now have buffer length we add copy it in the first field
28.607 + if (f->binary)
28.608 + memcpy((void *)(formatted[0].p), (void *)&pos, sizeof(PRInt32));
28.609 +
28.610 return pos;
28.611 }
28.612
28.613 @@ -1220,6 +1219,7 @@
28.614 {
28.615 const FlexFormat *f = log->format;
28.616 int pos = 0;
28.617 + int nullCount = 0;
28.618
28.619 // Format tokens for a request served from the accelerator cache
28.620 for (int ti = 0; ti < f->ntokens; ti++) {
28.621 @@ -1229,11 +1229,17 @@
28.622
28.623 const char *p = NULL;
28.624 int len = -1;
28.625 + formatted[ti].appendNull = PR_FALSE;
28.626
28.627 switch (t->type) {
28.628 case TOKEN_TEXT_OFFSET:
28.629 p = f->format + t->offset;
28.630 - len = t->len;
28.631 + // not writing beautification stuff in binary log
28.632 + if (f->binary) {
28.633 + len = 0;
28.634 + } else {
28.635 + len = t->len;
28.636 + }
28.637 break;
28.638
28.639 case TOKEN_TEXT_POINTER:
28.640 @@ -1242,49 +1248,91 @@
28.641 break;
28.642
28.643 case TOKEN_SYSDATE:
28.644 - len = flex_format_date(pool, date_format_clf, &p);
28.645 + if (f->binary)
28.646 + len = flex_format_binary <PRInt64> (pool, (PRInt64)
28.647 + ft_time(), &p);
28.648 + else
28.649 + len = flex_format_date(pool, date_format_clf, &p);
28.650 break;
28.651
28.652 case TOKEN_LOCALEDATE:
28.653 - len = flex_format_date(pool, date_format_locale, &p);
28.654 + if (f->binary)
28.655 + len = flex_format_binary <PRInt64> (pool, (PRInt64)
28.656 + ft_time(), &p);
28.657 + else
28.658 + len = flex_format_date(pool, date_format_locale, &p);
28.659 break;
28.660
28.661 case TOKEN_TIME:
28.662 - len = flex_format_64(pool, ft_time(), &p);
28.663 + if (f->binary)
28.664 + len = flex_format_binary <PRInt64> (pool, (PRInt64)
28.665 + ft_time(), &p);
28.666 + else
28.667 + len = flex_format_64(pool, ft_time(), &p);
28.668 break;
28.669
28.670 case TOKEN_RELATIVETIME:
28.671 - len = flex_format_64(pool, (PRInt64) ft_time() - log->epoch, &p);
28.672 + if (f->binary)
28.673 + len = flex_format_binary <PRInt64> (pool, (PRInt64) (ft_time()
28.674 + - log->epoch), &p);
28.675 + else
28.676 + len = flex_format_64(pool, (PRInt64) ft_time() - log->epoch,
28.677 + &p);
28.678 break;
28.679
28.680 case TOKEN_IP:
28.681 p = connection->remoteIP.buf;
28.682 len = connection->remoteIP.len;
28.683 + if (f->binary && p && (len > 0)) { // for '\0'
28.684 + formatted[ti].appendNull = PR_TRUE;
28.685 + nullCount++;
28.686 + }
28.687 break;
28.688
28.689 case TOKEN_METHOD_NUM:
28.690 PR_ASSERT(METHOD_GET == 1);
28.691 - p = "1";
28.692 - len = 1;
28.693 + if (f->binary)
28.694 + len = flex_format_binary <short> (pool, (short)1, &p);
28.695 + else {
28.696 + p = "1";
28.697 + len = 1;
28.698 + }
28.699 break;
28.700
28.701 case TOKEN_PROTV_NUM:
28.702 - len = flex_format_protv_num(pool, connection->httpHeader.GetNegotiatedProtocolVersion(), &p);
28.703 + if (f->binary)
28.704 + len = flex_format_binary <short> (pool, (short)
28.705 + connection->httpHeader.GetNegotiatedProtocolVersion(), &p);
28.706 + else
28.707 + len = flex_format_protv_num(pool,
28.708 + connection->httpHeader.GetNegotiatedProtocolVersion(), &p);
28.709 break;
28.710
28.711 case TOKEN_REQUEST_LINE:
28.712 p = connection->httpHeader.GetRequestLine().ptr;
28.713 len = connection->httpHeader.GetRequestLine().len;
28.714 + if (f->binary && p && (len > 0)) { // for '\0'
28.715 + formatted[ti].appendNull = PR_TRUE;
28.716 + nullCount++;
28.717 + }
28.718 break;
28.719
28.720 case TOKEN_REQUEST_LINE_URI:
28.721 p = connection->httpHeader.GetRequestAbsPath().ptr;
28.722 len = connection->httpHeader.GetRequestAbsPath().len;
28.723 + if (f->binary && p && (len > 0)) { // for '\0'
28.724 + formatted[ti].appendNull = PR_TRUE;
28.725 + nullCount++;
28.726 + }
28.727 break;
28.728
28.729 case TOKEN_REQUEST_LINE_URI_ABS_PATH:
28.730 p = connection->httpHeader.GetRequestAbsPath().ptr;
28.731 len = connection->httpHeader.GetRequestAbsPath().len;
28.732 + if (f->binary && p && (len > 0)) { // for '\0'
28.733 + formatted[ti].appendNull = PR_TRUE;
28.734 + nullCount++;
28.735 + }
28.736 break;
28.737
28.738 case TOKEN_REQUEST_LINE_URI_QUERY:
28.739 @@ -1292,37 +1340,71 @@
28.740
28.741 case TOKEN_REQUEST_LINE_PROTOCOL:
28.742 len = flex_format_protocol(pool, connection->httpHeader.GetClientProtocolVersion(), &p);
28.743 + if (f->binary && p && (len > 0)) { // for '\0'
28.744 + formatted[ti].appendNull = PR_TRUE;
28.745 + nullCount++;
28.746 + }
28.747 break;
28.748
28.749 case TOKEN_REQUEST_LINE_PROTOCOL_NAME:
28.750 p = "HTTP";
28.751 len = 4;
28.752 + if (f->binary) { // for '\0'
28.753 + formatted[ti].appendNull = PR_TRUE;
28.754 + nullCount++;
28.755 + }
28.756 break;
28.757
28.758 case TOKEN_REQUEST_LINE_PROTOCOL_VERSION:
28.759 len = flex_format_version(pool, connection->httpHeader.GetClientProtocolVersion(), &p);
28.760 + if (f->binary && p && (len > 0)) { // for '\0'
28.761 + formatted[ti].appendNull = PR_TRUE;
28.762 + nullCount++;
28.763 + }
28.764 break;
28.765
28.766 case TOKEN_METHOD:
28.767 p = "GET";
28.768 len = 3;
28.769 + if (f->binary) { // for '\0'
28.770 + formatted[ti].appendNull = PR_TRUE;
28.771 + nullCount++;
28.772 + }
28.773 break;
28.774
28.775 case TOKEN_STATUS_CODE:
28.776 - p = status;
28.777 - len = status_len;
28.778 + if (f->binary) {
28.779 + if (status) {
28.780 + short s = atoi(status);
28.781 + len = flex_format_binary <short>(pool, s, &p);
28.782 + }
28.783 + } else {
28.784 + p = status;
28.785 + len = status_len;
28.786 + }
28.787 break;
28.788
28.789 case TOKEN_CONTENT_LENGTH:
28.790 - len = flex_format_64(pool, cl, &p);
28.791 + if (f->binary)
28.792 + len = flex_format_binary <PRInt64> (pool, cl, &p);
28.793 + else
28.794 + len = flex_format_64(pool, cl, &p);
28.795 break;
28.796
28.797 case TOKEN_REFERER:
28.798 len = flex_format_hhstring(connection->httpHeader.GetReferer(), &p);
28.799 + if (f->binary && p && (len > 0)) { // for '\0'
28.800 + formatted[ti].appendNull = PR_TRUE;
28.801 + nullCount++;
28.802 + }
28.803 break;
28.804
28.805 case TOKEN_USER_AGENT:
28.806 len = flex_format_hhstring(connection->httpHeader.GetUserAgent(), &p);
28.807 + if (f->binary && p && (len > 0)) { // for '\0'
28.808 + formatted[ti].appendNull = PR_TRUE;
28.809 + nullCount++;
28.810 + }
28.811 break;
28.812
28.813 case TOKEN_AUTH_USER:
28.814 @@ -1331,12 +1413,26 @@
28.815 case TOKEN_VSID:
28.816 p = vsid;
28.817 len = vsid_len;
28.818 + if (f->binary && p && (len > 0)) { // for '\0'
28.819 + formatted[ti].appendNull = PR_TRUE;
28.820 + nullCount++;
28.821 + }
28.822 break;
28.823
28.824 case TOKEN_SUBSYSTEM:
28.825 // XXX elving differentiate between sync and async in log
28.826 p = "cache";
28.827 len = 5;
28.828 + if (f->binary) { // for '\0'
28.829 + formatted[ti].appendNull = PR_TRUE;
28.830 + nullCount++;
28.831 + }
28.832 + break;
28.833 +
28.834 + case TOKEN_RECORD_SIZE:
28.835 + // Field for buffer length
28.836 + len = sizeof(PRInt32);
28.837 + p = (char *)pool_malloc(pool, len);
28.838 break;
28.839
28.840 default:
28.841 @@ -1346,11 +1442,22 @@
28.842 }
28.843
28.844 if (p) {
28.845 - if (len == -1)
28.846 + if (len == -1) {
28.847 len = strlen(p);
28.848 + if (f->binary) { // for '\0'
28.849 + formatted[ti].appendNull = PR_TRUE;
28.850 + nullCount++;
28.851 + }
28.852 + }
28.853 } else {
28.854 - p = "-";
28.855 - len = 1;
28.856 + if (f->binary) { // for '\0'
28.857 + len = 0;
28.858 + formatted[ti].appendNull = PR_TRUE;
28.859 + nullCount++;
28.860 + } else {
28.861 + p = "-";
28.862 + len = 1;
28.863 + }
28.864 }
28.865
28.866 formatted[ti].p = p;
28.867 @@ -1359,13 +1466,19 @@
28.868 pos += len;
28.869 }
28.870
28.871 + pos += nullCount;
28.872 + // We now have buffer length we add copy it in the first field
28.873 + if (f->binary)
28.874 + memcpy((void *)(formatted[0].p), (void *)&pos, sizeof(PRInt32));
28.875 +
28.876 return pos;
28.877 }
28.878
28.879
28.880 /* ----------------------------- flex_memcpy ------------------------------ */
28.881
28.882 -static inline void flex_memcpy(char *buf, int& pos, const char *p, int len)
28.883 +static inline void flex_memcpy(char *buf, int& pos, const char *p, int len,
28.884 + PRBool appendNull)
28.885 {
28.886 // Access log format strings tend to contain a number of extremely short
28.887 // strings, so skip the memcpy call when it makes sense
28.888 @@ -1380,6 +1493,8 @@
28.889 pos += len;
28.890 break;
28.891 }
28.892 + if (appendNull)
28.893 + buf[pos++] = '\0';
28.894 }
28.895
28.896
28.897 @@ -1407,9 +1522,10 @@
28.898
28.899 /* --------------------------- flex_read_header --------------------------- */
28.900
28.901 -static int flex_read_header(const char *filename, NSString& format, NSString& time)
28.902 +static int flex_read_header(const char *filename, NSString& format,
28.903 + NSString& time, NSString& version)
28.904 {
28.905 - char buf[FORMAT_LINE_LEN + TIME_LINE_LEN + 1];
28.906 + char buf[FORMAT_LINE_LEN + TIME_LINE_LEN + BIN_LOG_VERSION_LINE_LEN + 1];
28.907
28.908 // Open the log file
28.909 SYS_FILE fd = system_fopenRO(filename);
28.910 @@ -1427,6 +1543,8 @@
28.911 const char *p = buf;
28.912 p = flex_parse_header_line(p, FORMAT_PREFIX, FORMAT_PREFIX_LEN, format);
28.913 p = flex_parse_header_line(p, TIME_PREFIX, TIME_PREFIX_LEN, time);
28.914 + p = flex_parse_header_line(p, BIN_LOG_VERSION_PREFIX,
28.915 + BIN_LOG_VERSION_PREFIX_LEN, version);
28.916
28.917 return len;
28.918 }
28.919 @@ -1434,7 +1552,9 @@
28.920
28.921 /* --------------------------- flex_create_log ---------------------------- */
28.922
28.923 -static FlexLog *flex_create_log(const VirtualServer *vs, const char *name, const char *filename, const char *format, PRBool enabled)
28.924 +static FlexLog *flex_create_log(const VirtualServer *vs, const char *name,
28.925 + const char *filename, const char *format,
28.926 + PRBool enabled, PRBool binary = PR_FALSE)
28.927 {
28.928 PR_ASSERT(vs);
28.929 PR_ASSERT(name);
28.930 @@ -1452,11 +1572,37 @@
28.931 // Compare the old header with the new header
28.932 NSString old_format;
28.933 NSString old_time;
28.934 - int rv = flex_read_header(filename, old_format, old_time);
28.935 + NSString old_binversion;
28.936 + int rv = flex_read_header(filename, old_format, old_time,
28.937 + old_binversion);
28.938 if (rv > 0) {
28.939 if (strncmp(format, old_format, FORMAT_LEN))
28.940 ereport(LOG_MISCONFIG, XP_GetAdminStr(DBT_flexLogError3), filename);
28.941 epoch = util_atoi64(old_time);
28.942 +
28.943 + if (binary) {
28.944 + // older log was not binary but this one is
28.945 + if (old_binversion.length() <= 0) {
28.946 + ereport(LOG_MISCONFIG,
28.947 + XP_GetAdminStr(DBT_flexLogError4), filename);
28.948 + // Do not start the server
28.949 + return NULL;
28.950 + } else if (strncmp(BIN_LOG_VERSION, old_binversion.data(),
28.951 + strlen(BIN_LOG_VERSION))) {
28.952 + // both are binary but their versions didnt match
28.953 + ereport(LOG_MISCONFIG,
28.954 + XP_GetAdminStr(DBT_flexLogError5));
28.955 + // Do not start the server
28.956 + return NULL;
28.957 + } // else if both the versions are same - ok
28.958 + } else if (old_binversion.length() > 0) {
28.959 + // If this log is NOT binary and older log is binary
28.960 + ereport(LOG_MISCONFIG,
28.961 + XP_GetAdminStr(DBT_flexLogError4), filename);
28.962 + // Do not start the server
28.963 + return NULL;
28.964 + }
28.965 + // else both are non-binary access logs - ok
28.966 }
28.967 }
28.968 }
28.969 @@ -1469,7 +1615,8 @@
28.970 // Initialize the FlexLog
28.971 log->next = NULL;
28.972 log->name = PERM_STRDUP(name);
28.973 - log->format = flex_acquire_format(format);
28.974 + log->format = flex_acquire_format(format, binary);
28.975 + log->format->binary = binary;
28.976 log->epoch = epoch;
28.977 log->enabled = enabled;
28.978 log->file = LogManager::getFile(filename);
28.979 @@ -1484,6 +1631,9 @@
28.980 break;
28.981 }
28.982 }
28.983 + if (binary)
28.984 + header.printf("%s%s%s", BIN_LOG_VERSION_PREFIX, BIN_LOG_VERSION,
28.985 + ENDLINE);
28.986
28.987 // Open the log file
28.988 LogManager::setHeader(log->file, header);
28.989 @@ -1504,7 +1654,9 @@
28.990 for (i = 0; i < vs->getAccessLogCount(); i++) {
28.991 const ServerXMLSchema::AccessLog *al = vs->getAccessLog(i);
28.992 if (!strcmp(al->name, name))
28.993 - return flex_create_log(vs, name, al->file, al->format, al->enabled);
28.994 + return flex_create_log(vs, name, al->file, al->format, al->enabled,
28.995 + al->mode.getEnumValue() ==
28.996 + ServerXMLSchema::AccessLogMode::ACCESSLOGMODE_BINARY);
28.997 }
28.998
28.999 // Look for a <server> <access-log>
28.1000 @@ -1512,7 +1664,9 @@
28.1001 for (i = 0; i < configuration->getAccessLogCount(); i++) {
28.1002 const ServerXMLSchema::AccessLog *al = configuration->getAccessLog(i);
28.1003 if (!strcmp(al->name, name))
28.1004 - return flex_create_log(vs, name, al->file, al->format, al->enabled);
28.1005 + return flex_create_log(vs, name, al->file, al->format, al->enabled,
28.1006 + al->mode.getEnumValue() ==
28.1007 + ServerXMLSchema::AccessLogMode::ACCESSLOGMODE_BINARY);
28.1008 }
28.1009
28.1010 // Look for a magnus.conf flex-init log template
28.1011 @@ -1641,18 +1795,21 @@
28.1012
28.1013 /* ------------------------------ flex_write ------------------------------ */
28.1014
28.1015 -static int flex_write(pool_handle_t *pool, FlexLog *log, FlexFormatted *formatted, int desired, LogBuffer* incomingHandle)
28.1016 +static int flex_write(pool_handle_t *pool, FlexLog *log,
28.1017 + FlexFormatted *formatted, int desired,
28.1018 + LogBuffer* incomingHandle, PRBool binary)
28.1019 {
28.1020 const FlexFormat *f = log->format;
28.1021
28.1022 // If the formatted tokens will fit in a buffer...
28.1023 - int available = LogManager::sizeMaxLogLine - ENDLINE_LEN;
28.1024 + int available = LogManager::sizeMaxLogLine - ((binary) ? 0 : ENDLINE_LEN);
28.1025 char* buf = NULL;
28.1026 if (desired <= available) {
28.1027 // Acquire a log buffer
28.1028 LogBuffer *handle = NULL;
28.1029 if (incomingHandle == NULL) {
28.1030 - buf = LogManager::lockBuffer(log->file, handle, desired + ENDLINE_LEN);
28.1031 + buf = LogManager::lockBuffer(log->file, handle, desired +
28.1032 + ((binary) ? 0 : ENDLINE_LEN));
28.1033 if (!buf)
28.1034 return -1;
28.1035 }
28.1036 @@ -1663,9 +1820,11 @@
28.1037
28.1038 // Copy the formatted tokens into the buffer
28.1039 for (int ti = 0; ti < f->ntokens; ti++)
28.1040 - flex_memcpy(buf, pos, formatted[ti].p, formatted[ti].len);
28.1041 + flex_memcpy(buf, pos, formatted[ti].p, formatted[ti].len,
28.1042 + formatted[ti].appendNull);
28.1043
28.1044 // Append EOL
28.1045 + if (!binary)
28.1046 for (int i = 0; i < ENDLINE_LEN; i++)
28.1047 buf[pos++] = ENDLINE[i];
28.1048
28.1049 @@ -1693,10 +1852,13 @@
28.1050 int greedy_desired = 0;
28.1051 int ungreedy_desired = 0;
28.1052 for (ti = 0; ti < f->ntokens; ti++) {
28.1053 - if (formatted[ti].len > avg_available) {
28.1054 - greedy_desired += formatted[ti].len;
28.1055 + if ((formatted[ti].len + (int)formatted[ti].appendNull)
28.1056 + > avg_available) {
28.1057 + greedy_desired += (formatted[ti].len +
28.1058 + (int)formatted[ti].appendNull);
28.1059 } else {
28.1060 - ungreedy_desired += formatted[ti].len;
28.1061 + ungreedy_desired += (formatted[ti].len +
28.1062 + (int)formatted[ti].appendNull);
28.1063 }
28.1064 }
28.1065
28.1066 @@ -1715,11 +1877,13 @@
28.1067 int greedy_allowed = 0;
28.1068 int ungreedy_allowed = 0;
28.1069 for (ti = 0; ti < f->ntokens; ti++) {
28.1070 - if (formatted[ti].len > avg_available) {
28.1071 - allowed[ti] = formatted[ti].len * 1024 / greedy_scale;
28.1072 + if ((formatted[ti].len + (int)formatted[ti].appendNull)
28.1073 + > avg_available) {
28.1074 + allowed[ti] = (formatted[ti].len + (int)formatted[ti].appendNull)
28.1075 + * 1024 / greedy_scale;
28.1076 greedy_allowed += allowed[ti];
28.1077 } else {
28.1078 - allowed[ti] = formatted[ti].len;
28.1079 + allowed[ti] = formatted[ti].len + (int)formatted[ti].appendNull;
28.1080 ungreedy_allowed += allowed[ti];
28.1081 }
28.1082 }
28.1083 @@ -1730,7 +1894,8 @@
28.1084 for (ti = 0; ti < f->ntokens; ti++) {
28.1085 if (leftover == 0)
28.1086 break;
28.1087 - if (formatted[ti].len > allowed[ti]) {
28.1088 + if ((formatted[ti].len + (int)formatted[ti].appendNull)
28.1089 + > allowed[ti]) {
28.1090 allowed[ti]++;
28.1091 leftover--;
28.1092 }
28.1093 @@ -1741,7 +1906,8 @@
28.1094 LogBuffer *handle = NULL;
28.1095 buf = NULL;
28.1096 if (incomingHandle == NULL) {
28.1097 - buf = LogManager::lockBuffer(log->file, handle, available + ENDLINE_LEN);
28.1098 + buf = LogManager::lockBuffer(log->file, handle, available +
28.1099 + ((binary) ? 0 : ENDLINE_LEN));
28.1100 if (!buf)
28.1101 return -1;
28.1102 } else {
28.1103 @@ -1752,17 +1918,31 @@
28.1104
28.1105 // Copy the formatted tokens into the buffer, truncating tokens as needed
28.1106 for (ti = 0; ti < f->ntokens; ti++) {
28.1107 - if (formatted[ti].len > allowed[ti]) {
28.1108 - flex_memcpy(buf, pos, formatted[ti].p, allowed[ti] - DOT_DOT_DOT_LEN);
28.1109 + if ((formatted[ti].len + (int)formatted[ti].appendNull)
28.1110 + > allowed[ti]) {
28.1111 + flex_memcpy(buf, pos, formatted[ti].p, allowed[ti]
28.1112 + - DOT_DOT_DOT_LEN - (int)formatted[ti].appendNull, 0);
28.1113 buf[pos++] = '.';
28.1114 buf[pos++] = '.';
28.1115 buf[pos++] = '.';
28.1116 + if (formatted[ti].appendNull)
28.1117 + buf[pos++] = '\0';
28.1118 + // size of actual record written is going to vary
28.1119 + if ((&f->tokens[0])->type == TOKEN_RECORD_SIZE) {
28.1120 + PRInt32 i;
28.1121 + memcpy(&i, buf, sizeof(PRInt32));
28.1122 + i = i + allowed[ti] - formatted[ti].len
28.1123 + - (int)formatted[ti].appendNull;
28.1124 + memcpy(buf, &i, sizeof(PRInt32));
28.1125 + }
28.1126 } else {
28.1127 - flex_memcpy(buf, pos, formatted[ti].p, formatted[ti].len);
28.1128 + flex_memcpy(buf, pos, formatted[ti].p, formatted[ti].len,
28.1129 + formatted[ti].appendNull);
28.1130 }
28.1131 }
28.1132
28.1133 // Append EOL
28.1134 + if (!binary)
28.1135 for (int i = 0; i < ENDLINE_LEN; i++)
28.1136 buf[pos++] = ENDLINE[i];
28.1137
28.1138 @@ -1821,7 +2001,7 @@
28.1139 int len = flex_format_nsapi(pb, sn, rq, log, formatted);
28.1140
28.1141 // Write the entry to the log file
28.1142 - int rv = flex_write(sn->pool, log, formatted, len, NULL);
28.1143 + int rv = flex_write(sn->pool, log, formatted, len, NULL, f->binary);
28.1144 if (rv == -1)
28.1145 return REQ_ABORTED;
28.1146 if (rv < len)
28.1147 @@ -1849,7 +2029,7 @@
28.1148 int len = flex_format_accel(log, pool, connection, status, status_len, vsid, vsid_len, cl, formatted);
28.1149
28.1150 // Write the entry to the log file
28.1151 - flex_write(pool, log, formatted, len, NULL);
28.1152 + flex_write(pool, log, formatted, len, NULL, f->binary);
28.1153
28.1154 }
28.1155
28.1156 @@ -1876,7 +2056,7 @@
28.1157
28.1158 // Format the tokens
28.1159 int len = flex_format_accel(log, pool, connection, status, status_len, vsid, vsid_len, cl, formatted);
28.1160 - int desired = len + ENDLINE_LEN;
28.1161 + int desired = len + ((f->binary)?0:ENDLINE_LEN);
28.1162 PRBool spaceAvailable = PR_FALSE;
28.1163
28.1164 int available = LogManager::sizeMaxLogLine;
28.1165 @@ -1902,5 +2082,5 @@
28.1166 }
28.1167
28.1168 // Write the entry to the log file
28.1169 - flex_write(pool, log, formatted, len, *handle);
28.1170 + flex_write(pool, log, formatted, len, *handle, f->binary);
28.1171 }
29.1 --- a/src/support/filecache/fileio.cpp Sun Jan 18 01:43:32 2009 -0800
29.2 +++ b/src/support/filecache/fileio.cpp Thu May 07 03:20:10 2009 -0700
29.3 @@ -667,6 +667,14 @@
29.4 rv = PR_SendFile(socket, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
29.5 timeout);
29.6 }
29.7 +
29.8 + // If there were no errors, set the rv value to the total size
29.9 + // written instead of the last chunk written. The caller may
29.10 + // do sanity check on number of bytes written based on returned
29.11 + // value
29.12 + if (rv >= 0)
29.13 + rv = hdrlen + finfo->pr.size + tlrlen;
29.14 +
29.15 }
29.16 }
29.17
30.1 --- a/src/support/xp/Makefile Sun Jan 18 01:43:32 2009 -0800
30.2 +++ b/src/support/xp/Makefile Thu May 07 03:20:10 2009 -0700
30.3 @@ -45,6 +45,10 @@
30.4 DLL_OBJS=xpatomic \
30.5 xpunit
30.6
30.7 +ifeq ($(UNAME_OS_RELEASE),5.11)
30.8 +LOCAL_DEF+= -DNO_INC_ATOMIC_ASM_WEAK
30.9 +endif
30.10 +
30.11 ifeq ($(OS_ARCH),SunOS)
30.12 DLL_OBJS+=atomic
30.13 endif
31.1 --- a/src/support/xp/i386/atomic.S Sun Jan 18 01:43:32 2009 -0800
31.2 +++ b/src/support/xp/i386/atomic.S Thu May 07 03:20:10 2009 -0700
31.3 @@ -74,7 +74,7 @@
31.4 /*
31.5 * Include the definitions for the libc weak aliases.
31.6 */
31.7 -#ifdef NON_OPENSOLARIS // XXX TODO FIX THIS
31.8 +#ifndef NO_INC_ATOMIC_ASM_WEAK
31.9 #include "../atomic_asm_weak.h"
31.10 #endif
31.11 #endif
32.1 --- a/templates/Makefile Sun Jan 18 01:43:32 2009 -0800
32.2 +++ b/templates/Makefile Thu May 07 03:20:10 2009 -0700
32.3 @@ -84,6 +84,8 @@
32.4
32.5 bin::
32.6 $(MKDIR_DASH_P) $(WS_INSTALL_ROOT)/bin
32.7 + $(PERL) replace_vars.pl $(WS_VARS) INPUT_DIR=$(BUILD_ROOT)/templates/install-bin/ OUTPUT_DIR=$(WS_INSTALL_ROOT)/bin/
32.8 + $(CHMOD) +x $(WS_INSTALL_ROOT)/bin/binlog
32.9 #$(CP) TBD/flexanlg ./bin/flexanlg
32.10 #$(CP) TBD ./bin/htpasswd
32.11
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/src/server/extras/Makefile Thu May 07 03:20:10 2009 -0700
33.3 @@ -0,0 +1,39 @@
33.4 +#
33.5 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33.6 +#
33.7 +# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
33.8 +#
33.9 +# THE BSD LICENSE
33.10 +#
33.11 +# Redistribution and use in source and binary forms, with or without
33.12 +# modification, are permitted provided that the following conditions are met:
33.13 +#
33.14 +# Redistributions of source code must retain the above copyright notice, this
33.15 +# list of conditions and the following disclaimer.
33.16 +# Redistributions in binary form must reproduce the above copyright notice,
33.17 +# this list of conditions and the following disclaimer in the documentation
33.18 +# and/or other materials provided with the distribution.
33.19 +#
33.20 +# Neither the name of the nor the names of its contributors may be
33.21 +# used to endorse or promote products derived from this software without
33.22 +# specific prior written permission.
33.23 +#
33.24 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33.25 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33.26 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33.27 +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
33.28 +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33.29 +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33.30 +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
33.31 +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33.32 +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
33.33 +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33.34 +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33.35 +#
33.36 +
33.37 +BUILD_ROOT=../../..
33.38 +include $(BUILD_ROOT)/make/defines.mk
33.39 +
33.40 +DIRS=binlog
33.41 +
33.42 +include $(BUILD_ROOT)/make/rules.mk
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/src/server/extras/binlog/Makefile Thu May 07 03:20:10 2009 -0700
34.3 @@ -0,0 +1,73 @@
34.4 +#
34.5 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
34.6 +#
34.7 +# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
34.8 +#
34.9 +# THE BSD LICENSE
34.10 +#
34.11 +# Redistribution and use in source and binary forms, with or without
34.12 +# modification, are permitted provided that the following conditions are met:
34.13 +#
34.14 +# Redistributions of source code must retain the above copyright notice, this
34.15 +# list of conditions and the following disclaimer.
34.16 +# Redistributions in binary form must reproduce the above copyright notice,
34.17 +# this list of conditions and the following disclaimer in the documentation
34.18 +# and/or other materials provided with the distribution.
34.19 +#
34.20 +# Neither the name of the nor the names of its contributors may be
34.21 +# used to endorse or promote products derived from this software without
34.22 +# specific prior written permission.
34.23 +#
34.24 +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34.25 +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34.26 +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34.27 +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
34.28 +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34.29 +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34.30 +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
34.31 +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34.32 +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34.33 +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
34.34 +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34.35 +#
34.36 +
34.37 +BUILD_ROOT=../../../..
34.38 +USE_NSPR=1
34.39 +MODULE=binlog
34.40 +include $(BUILD_ROOT)/make/defines.mk
34.41 +
34.42 +all::
34.43 +
34.44 +# object list is here
34.45 +LOCAL_SRC=binlog
34.46 +CCSRCS=$(LOCAL_SRC:=.cpp)
34.47 +
34.48 +LOCAL_INC=-I../../
34.49 +LOCAL_INC+=-I../../../support
34.50 +
34.51 +LOCAL_LIB+=ns-httpd40 support
34.52 +LOCAL_LIB+= nsfc nsprwrap nstime nstp xp ares3 xsd2cpp libdbm libsi18n
34.53 +LOCAL_LIB+= ssldap60 ldap60 prldap60
34.54 +LOCAL_LIB+= softokn3
34.55 +LOCAL_LIBDIRS+=../../webservd/$(OBJDIR)/
34.56 +LOCAL_LIBDIRS+=../../../support/support/$(OBJDIR)/
34.57 +LOCAL_LIBDIRS+=../../../support/filecache/$(OBJDIR)/
34.58 +LOCAL_LIBDIRS+=../../../support/NsprWrap/$(OBJDIR)/
34.59 +LOCAL_LIBDIRS+=../../../support/time/$(OBJDIR)/
34.60 +LOCAL_LIBDIRS+=../../../support/threadpool/$(OBJDIR)/
34.61 +LOCAL_LIBDIRS+=../../../support/xp/$(OBJDIR)/
34.62 +LOCAL_LIBDIRS+=../../../support/ares/$(OBJDIR)/
34.63 +LOCAL_LIBDIRS+=../../../support/libxsd2cpp/$(OBJDIR)/
34.64 +LOCAL_LIBDIRS+=../../../support/libdbm/$(OBJDIR)/
34.65 +LOCAL_LIBDIRS+=../../libsi18n/$(OBJDIR)/
34.66 +LOCAL_LIBDIRS+=$(LDAPSDK_LIBDIR)
34.67 +LOCAL_LIBDIRS+=$(NSS_LIBDIR)
34.68 +
34.69 +EXE_TARGET=binlog
34.70 +EXE_OBJS=binlog
34.71 +EXE_LIBS+=ns-httpd40 support
34.72 +
34.73 +SHIP_PRIVATE_BINARIES=binlog
34.74 +
34.75 +# this should always be last!
34.76 +include $(BUILD_ROOT)/make/rules.mk
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/src/server/extras/binlog/binlog.cpp Thu May 07 03:20:10 2009 -0700
35.3 @@ -0,0 +1,610 @@
35.4 +/*
35.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
35.6 + *
35.7 + * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
35.8 + *
35.9 + * THE BSD LICENSE
35.10 + *
35.11 + * Redistribution and use in source and binary forms, with or without
35.12 + * modification, are permitted provided that the following conditions are met:
35.13 + *
35.14 + * Redistributions of source code must retain the above copyright notice, this
35.15 + * list of conditions and the following disclaimer.
35.16 + * Redistributions in binary form must reproduce the above copyright notice,
35.17 + * this list of conditions and the following disclaimer in the documentation
35.18 + * and/or other materials provided with the distribution.
35.19 + *
35.20 + * Neither the name of the nor the names of its contributors may be
35.21 + * used to endorse or promote products derived from this software without
35.22 + * specific prior written permission.
35.23 + *
35.24 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35.25 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35.26 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35.27 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
35.28 + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
35.29 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35.30 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
35.31 + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35.32 + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
35.33 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35.34 + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.35 + *
35.36 + */
35.37 +/*
35.38 + * Binary access log format
35.39 + *
35.40 + * The default format is the CLF (common log file) format which is
35.41 + * "%Ses->client.ip% - %Req->vars.auth-user% [%SYSDATE%] \"%Req->reqpb.clf-request%\" %Req->srvhdrs.clf-status%
35.42 + * %Req->srvhdrs.content-length%"
35.43 + *
35.44 + * A binary format file consists of a new ASCII header "binlog-version=1.0".
35.45 + * In later releases, this version may get changed.
35.46 + *
35.47 + * The records have the following structure:
35.48 + * RECORD_LEN : PRInt32 4 bytes followed by the RECORD itself.
35.49 + * For CLF a typical binary record will be :
35.50 + *
35.51 + * TOKEN DATA TYPE WHAT IT CONTAINS
35.52 + * ----------------------------------------------------
35.53 + * TOKEN_RECORD_SIZE PRInt32 record length
35.54 + * TOKEN_IP String\0 Ses->client "ip"
35.55 + * TOKEN_AUTH_USER String\0 rq->vars "auth-user"
35.56 + * TOKEN_SYSDATE PRInt64 time when log entry was created
35.57 + * TOKEN_REQUEST_LINE String\0 rq->reqpb "clf-request"
35.58 + * TOKEN_STATUS_CODE short rq->srvhdrs "clf-status"
35.59 + * TOKEN_CONTENT_LENGTH PRInt64 rq->srvhdrs "content-length"
35.60 + *
35.61 + * Cosmetic stuff in format (of type TEXT_TOKEN_OFFSET) like spaces, quotes,
35.62 + * brackets, endline, etc. will not be written in binary log. They will be
35.63 + * added by the binlog reader.
35.64 + *
35.65 + * What other formats do
35.66 + *
35.67 + * TOKEN DATA TYPE WHAT IT CONTAINS
35.68 + * -----------------------------------------------------------------
35.69 + * TOKEN_TEXT_OFFSET None Nothing
35.70 + * TOKEN_METHOD_NUM short rq->method_num
35.71 + * TOKEN_PROTV_NUM short rq->protv_num
35.72 + * TOKEN_TEXT_POINTER String ??
35.73 + * TOKEN_MODEL String\0 model
35.74 + * TOKEN_REFERER String\0 rq->headers "referer"
35.75 + * TOKEN_USER_AGENT String\0 rq->headers "user-agent"
35.76 + * TOKEN_VSID String\0 virtual server id
35.77 + * TOKEN_DNS String\0 DNS of the client
35.78 + * TOKEN_REQUEST_LINE_URI String\0 Uri part from rq line
35.79 + * (includes query string)
35.80 + * TOKEN_REQUEST_LINE_URI_ABS_PATH String\0 Path part from rq line
35.81 + * (excludes query string)
35.82 + * TOKEN_REQUEST_LINE_URI_QUERY String\0 Query string from rq line
35.83 + * TOKEN_REQUEST_LINE_PROTOCOL String\0 Rq line protocol
35.84 + * For example "HTTP/1.0\0"
35.85 + * TOKEN_REQUEST_LINE_PROTOCOL_NAME String\0 Rq line protocol name
35.86 + * For example "HTTP\0"
35.87 + * TOKEN_REQUEST_LINE_PROTOCOL_VERSION String\0 Rq line protocol number
35.88 + * For example "1.0\0"
35.89 + * TOKEN_METHOD String\0 rq->reqpb "method"
35.90 + * TOKEN_STATUS_REASON String\0 Reason in rq->srvhdrs "status"
35.91 + * TOKEN_SUBSYSTEM String\0 "NSAPI\0"
35.92 + * TOKEN_COOKIE String\0 rq->headers "cookie"
35.93 + * TOKEN_PB_KEY String\0 pb key
35.94 + * TOKEN_PB_NAME String\0 pb value
35.95 + * TOKEN_SN_CLIENT_NAME String\0 sn->client
35.96 + * TOKEN_SN_CLIENT_KEY String\0 sn->client key
35.97 + * TOKEN_RQ_VARS_KEY String\0 rq->vars for key
35.98 + * TOKEN_RQ_VARS_NAME String\0 rq->vars value
35.99 + * TOKEN_RQ_REQPB_KEY String\0 rq->reqpb key
35.100 + * TOKEN_RQ_REQPB_NAME String\0 rq->reqpb value
35.101 + * TOKEN_RQ_HEADERS_KEY String\0 rq->headers key
35.102 + * TOKEN_RQ_HEADERS_NAME String\0 rq->headers value
35.103 + * TOKEN_RQ_SRVHDRS_KEY String\0 rq->srvhdrs key
35.104 + * TOKEN_RQ_SRVHDRS_NAME String\0 rq->srvhdrs value
35.105 + * TOKEN_DURATION PRUint64 duration
35.106 + * TOKEN_LOCALEDATE PRInt64 current time
35.107 + * TOKEN_TIME PRInt64 current time
35.108 + * TOKEN_RELATIVETIME PRInt64 current time minus time from
35.109 + * "time= ..." header line
35.110 + */
35.111 +#include <stdio.h>
35.112 +#include "netsite.h"
35.113 +#include "support/NSString.h"
35.114 +#include "time/nstime.h"
35.115 +#include "base/util.h"
35.116 +#include "base/date.h"
35.117 +#include "frame/log.h"
35.118 +#include "frame/object.h"
35.119 +#include "safs/flexlog.h"
35.120 +#include "safs/flexlogcommon.h"
35.121 +#include "base/pool.h"
35.122 +#ifdef XP_WIN32
35.123 +#include "wingetopt.h"
35.124 +#endif
35.125 +
35.126 +// T could be short, PRInt64 or PRUint64
35.127 +template <class T>
35.128 +inline PRInt32 convert(char *p, T& i)
35.129 +{
35.130 + PRInt32 l = sizeof(i);
35.131 + memcpy(&i, p, l);
35.132 + return l;
35.133 +}
35.134 +
35.135 +class BinLog
35.136 +{
35.137 +public :
35.138 + BinLog();
35.139 + ~BinLog();
35.140 + PRInt32 readLog(const char *filename);
35.141 +private :
35.142 + SYS_FILE _fd;
35.143 +
35.144 + char *_recordBuf;
35.145 + PRInt32 _currRecordBufSize;
35.146 +
35.147 + NSString _line;
35.148 +
35.149 + char _headerBuf[FORMAT_LINE_LEN + 1];
35.150 + PRInt32 _headerBufSize;
35.151 +
35.152 + NSString _time;
35.153 + NSString _version;
35.154 + NSString _format;
35.155 +
35.156 + FlexFormat *_f;
35.157 +
35.158 + PRInt32 openFile(const char *filename);
35.159 + PRInt32 parseLogFileHeaders(void);
35.160 + PRInt32 parseRecord(void);
35.161 + PRInt32 readNextRecord(void);
35.162 + PRInt32 readTillENDLINE(const char *prefix, NSString &val);
35.163 +};
35.164 +
35.165 +BinLog::BinLog(void)
35.166 +{
35.167 + _currRecordBufSize = 0;
35.168 +
35.169 + // use the same size working buffer for format, data, version
35.170 + // format line is the biggest line
35.171 + _headerBufSize = FORMAT_LINE_LEN + 1;
35.172 + PR_ASSERT(FORMAT_LINE_LEN > TIME_LINE_LEN);
35.173 + PR_ASSERT(FORMAT_LINE_LEN > BIN_LOG_VERSION_LINE_LEN);
35.174 +
35.175 + _recordBuf = NULL;
35.176 + _f = NULL;
35.177 + _fd = SYS_ERROR_FD;
35.178 +}
35.179 +
35.180 +BinLog::~BinLog(void)
35.181 +{
35.182 + if (_recordBuf)
35.183 + PERM_FREE(_recordBuf);
35.184 +
35.185 + // Destroy the FlexFormat
35.186 + for (int ti = 0; ti < _f->ntokens; ti++) {
35.187 + if (_f->tokens[ti].p)
35.188 + PERM_FREE(_f->tokens[ti].p);
35.189 + model_str_free(_f->tokens[ti].model);
35.190 + }
35.191 + if (_f->tokens)
35.192 + PERM_FREE(_f->tokens);
35.193 + if (_f->format)
35.194 + PERM_FREE(_f->format);
35.195 + PERM_FREE(_f);
35.196 + _f = NULL;
35.197 +
35.198 + if (_fd)
35.199 + PR_Close(_fd);
35.200 +
35.201 +}
35.202 +
35.203 +
35.204 +PRInt32 BinLog::parseRecord(void)
35.205 +{
35.206 + // note we already have read sizeof(PRInt32) record length
35.207 + char *p = _recordBuf;
35.208 +
35.209 + for (int ti = 0; ti < _f->ntokens; ti++) {
35.210 + const FlexToken *t = &_f->tokens[ti];
35.211 +
35.212 + PRInt32 len;
35.213 + short s;
35.214 + const char *arr = NULL;
35.215 + PRInt64 i;
35.216 + PRUint64 u;
35.217 + time_t tim;
35.218 +
35.219 + switch (t->type) {
35.220 + case TOKEN_TEXT_OFFSET:
35.221 + _line.append(_f->format + t->offset, t->len);
35.222 + break;
35.223 + case TOKEN_TEXT_POINTER:
35.224 + len = t->len;
35.225 + _line.append(p, len);
35.226 + p += len;
35.227 + break;
35.228 + case TOKEN_SYSDATE:
35.229 + case TOKEN_LOCALEDATE:
35.230 + p += convert(p, i);
35.231 +
35.232 + tim = (time_t)i;
35.233 +
35.234 + if (flex_format_time(NULL, tim, t->type, &arr) == -1) {
35.235 + fprintf(stderr, "Error converting time %lld to string\n",
35.236 + i);
35.237 + return -1;
35.238 + }
35.239 + _line.append(arr);
35.240 + pool_free(NULL, (void *)arr);
35.241 + break;
35.242 + // time_t
35.243 + case TOKEN_TIME:
35.244 + case TOKEN_RELATIVETIME:
35.245 + p += convert(p, i);
35.246 +
35.247 + tim = (time_t)i;
35.248 +
35.249 + if (flex_format_64(NULL,(PRInt64) tim, &arr) == -1) {
35.250 + fprintf(stderr, "Error converting time %lld to string\n",
35.251 + i);
35.252 + return -1;
35.253 + }
35.254 + _line.append(arr);
35.255 + pool_free(NULL, (void *)arr);
35.256 + break;
35.257 +
35.258 + // strings
35.259 + case TOKEN_MODEL:
35.260 + case TOKEN_IP:
35.261 + case TOKEN_AUTH_USER:
35.262 + case TOKEN_DNS:
35.263 + case TOKEN_REQUEST_LINE:
35.264 + case TOKEN_REQUEST_LINE_URI:
35.265 + case TOKEN_REQUEST_LINE_URI_ABS_PATH:
35.266 + case TOKEN_REQUEST_LINE_URI_QUERY:
35.267 + case TOKEN_REQUEST_LINE_PROTOCOL:
35.268 + case TOKEN_REQUEST_LINE_PROTOCOL_NAME:
35.269 + case TOKEN_REQUEST_LINE_PROTOCOL_VERSION:
35.270 + case TOKEN_METHOD:
35.271 + case TOKEN_STATUS_REASON:
35.272 + case TOKEN_REFERER:
35.273 + case TOKEN_USER_AGENT:
35.274 + case TOKEN_VSID:
35.275 + case TOKEN_SUBSYSTEM:
35.276 + case TOKEN_COOKIE:
35.277 + case TOKEN_PB_KEY:
35.278 + case TOKEN_PB_NAME:
35.279 + case TOKEN_SN_CLIENT_KEY:
35.280 + case TOKEN_SN_CLIENT_NAME:
35.281 + case TOKEN_RQ_VARS_KEY:
35.282 + case TOKEN_RQ_VARS_NAME:
35.283 + case TOKEN_RQ_REQPB_KEY:
35.284 + case TOKEN_RQ_REQPB_NAME:
35.285 + case TOKEN_RQ_HEADERS_KEY:
35.286 + case TOKEN_RQ_HEADERS_NAME:
35.287 + case TOKEN_RQ_SRVHDRS_KEY:
35.288 + case TOKEN_RQ_SRVHDRS_NAME:
35.289 + if (p && p[0] != '\0') {
35.290 + _line.append(p);
35.291 + len = strlen(p) + 1;
35.292 + p += len;
35.293 + } else {
35.294 + _line.append("-");
35.295 + p++;
35.296 + }
35.297 + break;
35.298 + // short
35.299 + case TOKEN_METHOD_NUM:
35.300 + case TOKEN_PROTV_NUM:
35.301 + case TOKEN_STATUS_CODE:
35.302 + p += convert(p, s);
35.303 + _line.printf("%d", s);
35.304 + break;
35.305 +
35.306 + // PRInt64
35.307 + case TOKEN_CONTENT_LENGTH:
35.308 + p += convert(p, i);
35.309 +
35.310 + // convert PRInt64 to string
35.311 + if (flex_format_64(NULL, i, &arr) == -1) {
35.312 + fprintf(stderr,
35.313 + "Error converting content length %lld to string\n",
35.314 + i);
35.315 + return -1;
35.316 + }
35.317 + _line.append(arr);
35.318 + pool_free(NULL, (void *)arr);
35.319 + break;
35.320 +
35.321 + // PRUint64
35.322 + case TOKEN_DURATION:
35.323 + p += convert(p, u);
35.324 +
35.325 + // convert PRUint64 to string
35.326 + char arr1[30];
35.327 + memset(arr1, '\0', sizeof(arr1));
35.328 + if (PR_snprintf(arr1, sizeof(arr1), "%llu", u) != -1)
35.329 + _line.append(arr1);
35.330 + break;
35.331 +
35.332 + case TOKEN_RECORD_SIZE:
35.333 + // Field to add buffer length do nothing as it is already read
35.334 + break;
35.335 + default:
35.336 + PR_ASSERT(0);
35.337 + break;
35.338 + }
35.339 + }
35.340 + return 0;
35.341 +}
35.342 +
35.343 +PRInt32 BinLog::readTillENDLINE(const char *prefix, NSString &val)
35.344 +{
35.345 +
35.346 + memset(_headerBuf, '\0', _headerBufSize);
35.347 +
35.348 + // read ...=.... (till endline)
35.349 + char c = 'a';
35.350 + char *p = _headerBuf;
35.351 + PRInt32 totalBytesRead = 0;
35.352 + PRInt32 bytes = 0;
35.353 + do {
35.354 + bytes = PR_Read(_fd, (void *)&c, sizeof(char));
35.355 + if (bytes == 0)
35.356 + break;
35.357 + if (bytes != sizeof(char)) {
35.358 + fprintf(stderr, "Error reading %s... line. %d bytes read.\n",
35.359 + prefix, bytes);
35.360 + return -1;
35.361 + }
35.362 + *p = c;
35.363 + p++;
35.364 + totalBytesRead++;
35.365 + } while ((c != ENDLINE[0]) && (totalBytesRead < _headerBufSize));
35.366 +
35.367 + // If no bytes are read error
35.368 + if (totalBytesRead <= 0) {
35.369 + fprintf(stderr, "Error reading %s... line.\n", prefix);
35.370 + return -1;
35.371 + }
35.372 +
35.373 + // read ENDLINE
35.374 + // ENDLINE is '\r\n' (windows) and is '\n' on Unix
35.375 + if (c == ENDLINE[0] && ENDLINE_LEN > 1) {
35.376 + for (int j = 0; j < ENDLINE_LEN - 1; j++) {
35.377 + bytes = PR_Read(_fd, (void *)p, sizeof(char));
35.378 + if (bytes != sizeof(char)) {
35.379 + fprintf(stderr, "Error reading end of line.\n");
35.380 + return -1;
35.381 + }
35.382 + p++;