OSDN Git Service

date function, http method, md5 function, etc.
authorvisor <visor@users.sourceforge.jp>
Mon, 13 Aug 2012 14:36:26 +0000 (23:36 +0900)
committervisor <visor@users.sourceforge.jp>
Mon, 13 Aug 2012 14:36:26 +0000 (23:36 +0900)
14 files changed:
Makefile.src
ext/ml-sqlite3.cc
lib/http.cc
lib/http.h
lib/util_string.cc
lib/util_string.h
modules/ml-http.cc
modules/ml-security.cc
modules/ml-security.h
modules/ml-string.cc
modules/ml-string.h
modules/ml-time.cc
modules/motor-function.cc
wiki/wikiline.cc

index e597cd0..8fcbddf 100644 (file)
@@ -1,4 +1,5 @@
 MSRCS += ml-security.cc
+MLDADD += -lmd
 #MSRCS += ml-fetch.cc
 #MLDADD += -lfetch
 .ifdef UTF8JP
index e1571e7..9ffbebf 100644 (file)
@@ -12,6 +12,7 @@
 #include "util_string.h"
 #include "utf8.h"
 #include <exception>
+#include <unistd.h>
 
 //#define  DB5_DBDIR_HACK      1
 #define  DEFAULT_RETRY 10
@@ -27,7 +28,7 @@
 */
 
 static void  randomSleep () {
-    usleep (10000 + 100000 * randDouble ());
+    usleep ((useconds_t)(10000 + 100000 * randDouble ()));
 }
 
 int  MLSqlite3::open (ustring& name) {
index 586d8c7..d34f5d7 100644 (file)
@@ -302,14 +302,28 @@ bool  HTTPSend::submit (TcpClient& client, TcpBuf& buf, MlEnv* mlenv) {
 #ifdef DEBUG2
        std::cerr << q;
 #endif /* DEBUG */
-       if (fpost) {
+//     if (fpost) {
+//     if (method == M_POST) {
+       switch (method) {
+       case M_POST:
            if (formData) {
                writeFileForm (&client, mlenv);
            } else if (rawquery.length () > 0) {
                client.write (&*rawquery.begin (), rawquery.length ());
+           } else if (rawqueryfile.length () > 0) {
+               writeFile (&client, rawqueryfile);
            } else {
                writeQueryForm (params (), client);
            }
+           break;
+       case M_PUT:
+           if (rawquery.length () > 0) {
+               client.write (&*rawquery.begin (), rawquery.length ());
+           } else if (rawqueryfile.length () > 0) {
+               writeFile (&client, rawqueryfile);
+           }
+           break;
+       default:;
        }
        client.flush_write ();
        status = HTTP_QUERY;
@@ -402,15 +416,24 @@ ustring  HTTPSend::query (MlEnv* mlenv) {
        assert (0);
     }
     q.append (uSPC).append (path);
-    if (fpost) {
+//    if (fpost) {
+//    if (method == M_POST) {
+    switch (method) {
+    case M_POST:
        if (formData)
            makeSeparator ();
        if (getparams ()) {
            q.append (CharConst ("?"));
            appendQueryForm (getparams (), q);
        }
-       q.append (CharConst (" HTTP/1.0" kCRLF));
-    } else {
+       break;
+    case M_PUT:
+       if (getparams ()) {
+           q.append (CharConst ("?"));
+           appendQueryForm (getparams (), q);
+       }
+       break;
+    default:
        if (getparams ()) {
            q.append (CharConst ("?"));
            appendQueryForm (getparams (), q);
@@ -418,8 +441,8 @@ ustring  HTTPSend::query (MlEnv* mlenv) {
            q.append (CharConst ("?"));
            appendQueryForm (params (), q);
        }
-       q.append (CharConst (" HTTP/1.0" kCRLF));
     }
+    q.append (CharConst (" HTTP/1.0" kCRLF));
     if (reqhost.length () > 0) {
        makeHeader (q, ustring (CharConst ("Host")), reqhost);
     } else {
@@ -440,16 +463,35 @@ ustring  HTTPSend::query (MlEnv* mlenv) {
     for (std::vector<mapelem>::iterator i = header_req.begin (); i < header_req.end (); i ++) {
        makeHeader (q, (*i).first, (*i).second);
     }
-    if (fpost)
+//    if (fpost)
+//    if (method == M_POST)
+    switch (method) {
+    case M_POST:
        if (formData) {
            q.append (CharConst ("Content-Length: ")).append (to_ustring (writeFileForm (NULL, mlenv))).append (uCRLF);
 //         q.append (CharConst ("Content-Type: multipart/form-data; boundary=")).append (separator).append (uCRLF);
            querytype.assign (CharConst ("multipart/form-data; boundary=")).append (separator);
        } else if (rawquery.length () > 0) {
            q.append (CharConst ("Content-Length: ")).append (to_ustring (rawquery.length ())).append (uCRLF);
+       } else if (rawqueryfile.length () > 0) {
+           off_t  s;
+           fileSize (rawqueryfile, s);
+           q.append (CharConst ("Content-Length: ")).append (to_ustring (s)).append (uCRLF);
        } else {
            q.append (CharConst ("Content-Length: ")).append (to_ustring (queryFormSize (params ()))).append (uCRLF);
        }
+       break;
+    case M_PUT:
+       if (rawquery.length () > 0) {
+           q.append (CharConst ("Content-Length: ")).append (to_ustring (rawquery.length ())).append (uCRLF);
+       } else if (rawqueryfile.length () > 0) {
+           off_t  s;
+           fileSize (rawqueryfile, s);
+           q.append (CharConst ("Content-Length: ")).append (to_ustring (s)).append (uCRLF);
+       }
+       break;
+    default:;
+    }
     if (querytype.length () > 0)
        q.append (CharConst ("Content-Type: ")).append (querytype).append (uCRLF);
     q.append (CharConst ("Connection: close" kCRLF kCRLF));
index 5f03fbf..2dddccb 100644 (file)
@@ -64,7 +64,7 @@ class  HTTPSend {
        HTTP_HEAD,
        HTTP_DONE,
     }  status;
-    bool  fpost;
+//    bool  fpost;
 //    ustring  method;
     enum method_t {
        M_GET, M_HEAD, M_POST, M_OPTIONS, M_PUT, M_DELETE,
@@ -77,6 +77,7 @@ class  HTTPSend {
     MNodePtr  params;
     MNodePtr  getparams;
     ustring  rawquery;
+    ustring  rawqueryfile;
     ustring  querytype;
     MNodePtr  fileparams_store;
     MNodePtr  fileparams_storage;
@@ -98,7 +99,7 @@ class  HTTPSend {
     HTTPSend () {
        method = M_GET;
        status = HTTP_INIT;
-       fpost = false;
+//     fpost = false;
        paramsLen = 0;
        responseCode = 0;
        useproxy = false;
@@ -108,14 +109,14 @@ class  HTTPSend {
 //    virtual void  setMethod (const ustring& _method, bool fpost);
     virtual void  setMethod (method_t _method) {
        method = _method;
-       if (method == M_POST)
-           fpost = true;
-       else
-           fpost = false;
+//     if (method == M_POST)
+//         fpost = true;
+//     else
+//         fpost = false;
     };
     virtual void  setPostFileMethod () {
        method = M_POST;
-       fpost = true;
+//     fpost = true;
        formData = true;
     };
     virtual bool  submit (TcpClient& client, TcpBuf& buf, MlEnv* mlenv);
index 6421035..6951fe3 100644 (file)
@@ -1246,9 +1246,10 @@ static ustring  colpad0 (int n, const ustring& src) {
  ${W}, ${w}
  ${o}
 */
-ustring  formatDateString (const ustring& format, time_t tm) {
+//ustring  formatDateString (const ustring& format, time_t tm) {
+ustring  formatDateString (const ustring& format, struct tm& v) {
     ustring  ans;
-    struct tm  v;
+//    struct tm  v;
     uiterator  b, e;
     umatch  m;
     int  pc;
@@ -1256,7 +1257,7 @@ ustring  formatDateString (const ustring& format, time_t tm) {
     static uregex  re ("\\$\\{(([YMDhmsWwo])(:([0-9]))?|M:((name)|(ab)|(abname)))\\}");
     std::vector<ustring>  fpar;
 
-    localtime_r (&tm, &v);
+//    localtime_r (&tm, &v);
     b = format.begin ();
     e = format.end ();
     while (usearch (b, e, m, re)) {
@@ -1333,3 +1334,17 @@ ustring  toLower (const ustring& str) {
 ustring  toUpper (const ustring& str) {
     return boost::to_upper_copy (str);
 }
+
+ustring  hexEncode (const ustring& data) {
+    ustring  ans;
+    uiterator  b, e;
+
+    ans.reserve (data.length () * 2);
+    b = data.begin ();
+    e = data.end ();
+    for (; b < e; b ++) {
+       ans.append (1, hexchar ((*b >> 4) & 0x0f));
+       ans.append (1, hexchar (*b & 0x0f));
+    }
+    return ans;
+}
index 2d26a51..c95d697 100644 (file)
@@ -109,8 +109,10 @@ ustring  toLower (uiterator b, uiterator e);
 
 class  MNodePtr;
 ustring  formatString (const ustring& format, boost::ptr_vector<MNodePtr>& par);
-ustring  formatDateString (const ustring& format, time_t tm);
+//ustring  formatDateString (const ustring& format, time_t tm);
+ustring  formatDateString (const ustring& format, struct tm& v);
 ustring  toLower (const ustring& str);
 ustring  toUpper (const ustring& str);
+ustring  hexEncode (const ustring& data);
 
 #endif /* UTIL_STRING_H */
index f60d470..715076f 100644 (file)
@@ -330,6 +330,7 @@ MNode*  ml_response_no_cache (MNode* cell, MlEnv* mlenv) {
        [:id STRING] [:password STRING | :pw STRING]
        [:query '((NAME . VALUE) ...)] [:get-query '((NAME . VALUE) ...)]
        [:raw-query TEXT]
+       [:raw-file-serial NAME] [:raw-file-named NAME] [:raw-file-static NAME]
        [:query-type MIMETYPE]
        [:post-file-serial '((NAME . VALUE) ...)]
        [:post-file-named '((NAME . VALUE) ...)]
@@ -383,6 +384,9 @@ MNode*  ml_http_get (MNode* cell, MlEnv* mlenv) {
        {CharConst ("no-verify"), true},        // 24
        {CharConst ("raw-query"), false},       // 25
        {CharConst ("query-type"), false},      // 26
+       {CharConst ("raw-file-serial"), false}, // 27
+       {CharConst ("raw-file-named"), false},  // 28
+       {CharConst ("raw-file-static"), false}, // 29
        {NULL, 0, 0}
     };
 
@@ -462,6 +466,12 @@ MNode*  ml_http_get (MNode* cell, MlEnv* mlenv) {
        if (!checkASCII (obj.http->querytype))
            throw (obj.http->querytype + ustring (CharConst (": bad type")));
     }
+    if (keywords[27])          // raw-file-serial
+       obj.http->rawqueryfile = mlenv->env->path_store_file (eval_str (keywords[27], mlenv));
+    if (keywords[28])          // raw-file-named
+       obj.http->rawqueryfile = mlenv->env->path_storage_file (eval_str (keywords[28], mlenv));
+    if (keywords[29])          // raw-file-static
+       obj.http->rawqueryfile = mlenv->env->path_static_file (eval_str (keywords[29], mlenv));
     
     url_sub (url, obj.http);
     if (obj.http->proto.empty ()) {
index 9394795..3675a30 100644 (file)
@@ -1,12 +1,15 @@
 #include "ml-security.h"
+#include "ml-store.h"
 #include "ml.h"
 #include "mlenv.h"
 #include "expr.h"
 #include "util_base64.h"
 #include "util_string.h"
+#include "filemacro.h"
 #include "ustring.h"
+#include <md5.h>
 #include <openssl/hmac.h>
-
+#include <sys/types.h>
 
 /*DOC:
 ==cryptographic functions
@@ -47,11 +50,12 @@ MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv) {
 
     HMAC (EVP_sha1 (), key.c_str (), key.length (), uchar_type (text.c_str ()), text.length (), md, &md_len);
 
+    ans.assign (char_type (md), md_len);
     switch (encode) {
     case ENC_HEX:
+       ans = hexEncode (ans);
        break;
     case ENC_BASE64:
-       ans.assign (char_type (md), md_len);
        ans = base64Encode (ans.begin (), ans.end ());
        break;
     default:
@@ -60,3 +64,74 @@ MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv) {
 
     return newMNode_str (new ustring (ans));
 }
+
+/*DOC:
+===md5-file===
+ (md5-file FILENAME [#serial | #named | #static | :serial BOOL | :named BOOL | :static BOOL] [#hex | #base64 | :hex BOOL | :base64 BOOL]) -> STRING
+
+*/
+//#AFUNC       md5-file        ml_md5_file
+MNode*  ml_md5_file (MNode* cell, MlEnv* mlenv) {
+    MNode*  arg = cell->cdr ();
+    ustring  name;
+    ustring  src;
+    StoreType  storetype;
+    enum {
+       ENC_HEX,
+       ENC_BASE64,
+    }  encode = ENC_HEX;
+    ustring  ans;
+    std::vector<MNode*>  params;
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("serial"), true},
+       {CharConst ("named"), true},
+       {CharConst ("static"), true},
+       {CharConst ("hex"), true},
+       {CharConst ("base64"), true},
+       {NULL, 0, 0}
+    };
+
+    setParams (arg, 1, &params, kwlist, &keywords, NULL);
+    name = eval_str (params[0], mlenv);
+    if (keywords[0] && eval_bool (keywords[0], mlenv)) // serial
+       storetype.setSerial ();
+    if (keywords[1] && eval_bool (keywords[1], mlenv)) // named
+       storetype.setNamed ();
+    if (keywords[2] && eval_bool (keywords[2], mlenv)) // static
+       storetype.setStatic ();
+    if (keywords[3] && eval_bool (keywords[3], mlenv)) // hex
+       encode = ENC_HEX;
+    if (keywords[4] && eval_bool (keywords[4], mlenv)) // base64
+       encode = ENC_BASE64;
+    src = storetype.src (mlenv, name);
+
+    if (src.length () > 0) {
+       MD5_CTX  ctx;
+       FileMacro  f;
+       ssize_t  len;
+       u_char buf[1024];
+
+       MD5Init (&ctx);
+       if (f.openRead (src.c_str ())) {
+           while ((len = f.read (buf, 1024)) > 0) {
+               MD5Update (&ctx, buf, len);
+           }
+           MD5Final (buf, &ctx);
+           ans.assign (char_type (buf), 16);
+           switch (encode) {
+           case ENC_HEX:
+               ans = hexEncode (ans);
+               break;
+           case ENC_BASE64:
+               ans = base64Encode (ans.begin (), ans.end ());
+               break;
+           default:
+               assert (0);
+           }
+           return newMNode_str (new ustring (ans));
+       }
+    }
+    return NULL;
+}
+
index 4f670d4..c51f221 100644 (file)
@@ -8,5 +8,6 @@ class  MNode;
 class  MlEnv;
 
 MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv);
+MNode*  ml_md5_file (MNode* cell, MlEnv* mlenv);
 
 #endif /* ML_SECURITY_H */
index 319b241..d508adb 100644 (file)
@@ -708,8 +708,9 @@ MNode*  ml_random_key (MNode* cell, MlEnv* mlenv) {
 }
 
 /*DOC:
-===date-format===
+===date-format, gmdate-format===
  (date-format FORMAT INTEGER) -> STRING
+ (gmdate-format FORMAT INTEGER) -> STRING
 
  ${Y:4}, ${Y:2}
  ${M:2}, ${M}
@@ -726,6 +727,7 @@ MNode*  ml_date_format (MNode* cell, MlEnv* mlenv) {
     MNode*  arg = cell->cdr ();
     ustring  format;
     time_t  tm;
+    struct tm  tmv;
 
     if (! arg)
        throw (uErrorWrongNumber);
@@ -736,7 +738,29 @@ MNode*  ml_date_format (MNode* cell, MlEnv* mlenv) {
     if (arg)
        throw (uErrorWrongNumber);
 
-    return newMNode_str (new ustring (formatDateString (format, tm)));
+    localtime_r (&tm, &tmv);
+    return newMNode_str (new ustring (formatDateString (format, tmv)));
+}
+
+//#AFUNC       gmdate-format   ml_gmdate_format
+//#WIKIFUNC    gmdate-format
+MNode*  ml_gmdate_format (MNode* cell, MlEnv* mlenv) {
+    MNode*  arg = cell->cdr ();
+    ustring  format;
+    time_t  tm;
+    struct tm  tmv;
+
+    if (! arg)
+       throw (uErrorWrongNumber);
+    format = eval_str (arg->car (), mlenv);
+    nextNodeNonNil (arg);
+    tm = eval_int (arg->car (), mlenv);
+    nextNode (arg);
+    if (arg)
+       throw (uErrorWrongNumber);
+
+    gmtime_r (&tm, &tmv);
+    return newMNode_str (new ustring (formatDateString (format, tmv)));
 }
 
 /*DOC:
index 8a3b625..eed6fa6 100644 (file)
@@ -24,6 +24,7 @@ MNode*  ml_pad0 (MNode* cell, MlEnv* mlenv);
 MNode*  ml_ellipsis (MNode* cell, MlEnv* mlenv);
 MNode*  ml_string_format (MNode* cell, MlEnv* mlenv);
 MNode*  ml_date_format (MNode* cell, MlEnv* mlenv);
+MNode*  ml_gmdate_format (MNode* cell, MlEnv* mlenv);
 MNode*  ml_random_key (MNode* cell, MlEnv* mlenv);
 MNode*  ml_to_string (MNode* cell, MlEnv* mlenv);
 MNode*  ml_to_sexp (MNode* cell, MlEnv* mlenv);
index 210fa42..60a27ab 100644 (file)
@@ -26,13 +26,17 @@ static MNode*  timeval6 (struct tm* v) {
     return ans.release ();
 }
 
-static MNode*  dateval4 (struct tm* v) {
+static MNode*  dateval7 (struct tm* v) {
     MNodeList  ans;
 
     ans.append (newMNode_num (v->tm_year + 1900));
     ans.append (newMNode_num (v->tm_mon + 1));
     ans.append (newMNode_num (v->tm_mday));
     ans.append (newMNode_num (v->tm_wday));
+    ans.append (newMNode_num (v->tm_hour));
+    ans.append (newMNode_num (v->tm_min));
+    ans.append (newMNode_num (v->tm_sec));
+
     return ans.release ();
 }
 
@@ -42,6 +46,7 @@ static MNode*  timeval3 (struct tm* v) {
     ans.append (newMNode_num (v->tm_hour));
     ans.append (newMNode_num (v->tm_min));
     ans.append (newMNode_num (v->tm_sec));
+
     return ans.release ();
 }
 
@@ -89,7 +94,7 @@ MNode*  ml_datetime3 (MNode* cell, MlEnv* mlenv) {
 
 /*DOC:
 ===to-date4===
- (to-date4 INTEGER) -> (YEAR MONTH DAY WEEK)
+ (to-date4 INTEGER) -> (YEAR MONTH DAY WEEK HOUR MINUTE SECOND)
 
 */
 //#AFUNC       to-date4        ml_date4
@@ -108,7 +113,7 @@ MNode*  ml_date4 (MNode* cell, MlEnv* mlenv) {
 
     localtime_r (&tm, &v);
     
-    return dateval4 (&v);
+    return dateval7 (&v);
 }
 
 /*DOC:
@@ -218,7 +223,7 @@ MNode*  ml_gmdatetime3 (MNode* cell, MlEnv* mlenv) {
 
 /*DOC:
 ===to-gmdate4===
- (to-gmdate4 INTEGER) -> (YEAR MONTH DAY WEEK)
+ (to-gmdate4 INTEGER) -> (YEAR MONTH DAY WEEK HOUR MINUTE SECOND)
 
 */
 //#AFUNC       to-gmdate4      ml_gmdate4
@@ -237,7 +242,7 @@ MNode*  ml_gmdate4 (MNode* cell, MlEnv* mlenv) {
 
     gmtime_r (&tm, &v);
     
-    return dateval4 (&v);
+    return dateval7 (&v);
 }
 
 /*DOC:
index 715a0ae..611bb26 100644 (file)
@@ -162,6 +162,7 @@ void  mf_wiki (const std::vector<ustring>& args, MlEnv* mlenv) {
 //#MTFUNC      date    mf_date
 void  mf_date (const std::vector<ustring>& args, MlEnv* mlenv) {
     time_t  tm;
+    struct tm  tmv;
     ustring  format;
 //    boost::ptr_vector<MNodePtr>  par;
     int  i;
@@ -178,7 +179,8 @@ void  mf_date (const std::vector<ustring>& args, MlEnv* mlenv) {
            }
            if (format.length () == 0)
                format = uTimeFormat;
-           mlenv->env->output->out_toHTML (formatDateString (format, tm));
+           localtime_r (&tm, &tmv);
+           mlenv->env->output->out_toHTML (formatDateString (format, tmv));
        }
     }
 }
index 3cb4460..0d3009e 100644 (file)
@@ -627,6 +627,7 @@ bool  wl_date (WikiMotorObjVecVec* args, WikiMotorObjVec* arg2, WikiMotorObjVec&
     WikiMotorObjVecVec::const_iterator  e = args->end ();
     ustring  val;
     time_t  tm;
+    struct tm  tmv;
     ustring  format;
 //    boost::ptr_vector<MNodePtr>  par;
 
@@ -641,7 +642,8 @@ bool  wl_date (WikiMotorObjVecVec* args, WikiMotorObjVec* arg2, WikiMotorObjVec&
                format = uTimeFormat;
            
 //         out->out_toHTML (formatDateString (format, tm));
-           out.push_back (WikiMotorObjPtr (new WikiMotorObjText (formatDateString (format, tm))));
+           localtime_r (&tm, &tmv);
+           out.push_back (WikiMotorObjPtr (new WikiMotorObjText (formatDateString (format, tmv))));
        }
        return true;
     }