OSDN Git Service

$http-get, hmac-sha1 functions.
authorvisor <visor@users.sourceforge.jp>
Tue, 27 Dec 2011 13:46:12 +0000 (22:46 +0900)
committervisor <visor@users.sourceforge.jp>
Tue, 27 Dec 2011 13:46:12 +0000 (22:46 +0900)
Makefile.src
lib/http.cc
lib/http.h
modules/ml-http.cc
modules/ml-security.cc [new file with mode: 0644]
modules/ml-security.h [new file with mode: 0644]

index dd1ea30..e597cd0 100644 (file)
@@ -1,3 +1,4 @@
+MSRCS += ml-security.cc
 #MSRCS += ml-fetch.cc
 #MLDADD += -lfetch
 .ifdef UTF8JP
index 176522d..b4edafb 100644 (file)
@@ -282,13 +282,15 @@ void  HTTPResponse::forbiddenResponse (MotorOutput* out, MotorEnv* env) {
                             "Forbidden.\n"));
 }
 
-void  HTTPSend::setMethod (const ustring& _method, bool fpost) {
+#if 0
+void  HTTPSend::setMethod (const ustring& _method, bool _fpost) {
     static uregex  re ("^(GET|HEAD|POST|OPTIONS|PUT|DELETE|TRACE|PATCH|LINK|UNLINK)$");
     if (checkRe (_method, re)) {
        method = _method;
-       fpostdata = fpost;
+       fpost = _fpost;
     }
 }
+#endif
 
 bool  HTTPSend::submit (TcpClient& client, TcpBuf& buf, MlEnv* mlenv) {
     bool  rc;
@@ -313,7 +315,7 @@ bool  HTTPSend::submit (TcpClient& client, TcpBuf& buf, MlEnv* mlenv) {
 #ifdef DEBUG2
        std::cerr << q;
 #endif /* DEBUG */
-       if (fpostdata) {
+       if (fpost) {
            if (formData) {
                writeFileForm (&client, mlenv);
            } else {
@@ -376,11 +378,45 @@ void  HTTPSend::makeCookieHeader (ustring& q) {
 ustring  HTTPSend::query (MlEnv* mlenv) {
     ustring  q;
 
-    if (method.length () == 0) {
-       method.assign (CharConst ("GET"));
-    }
-    q.assign (method).append (uSPC).append (path);
-    if (fpostdata) {
+//    if (method.length () == 0) {
+//     method.assign (CharConst ("GET"));
+//    }
+    switch (method) {
+    case M_GET:
+       q.assign (CharConst ("GET"));
+       break;
+    case M_HEAD:
+       q.assign (CharConst ("HEAD"));
+       break;
+    case M_POST:
+       q.assign (CharConst ("POST"));
+       break;
+    case M_OPTIONS:
+       q.assign (CharConst ("OPTIONS"));
+       break;
+    case M_PUT:
+       q.assign (CharConst ("PUT"));
+       break;
+    case M_DELETE:
+       q.assign (CharConst ("DELETE"));
+       break;
+    case M_TRACE:
+       q.assign (CharConst ("TRACE"));
+       break;
+    case M_PATCH:
+       q.assign (CharConst ("PATCH"));
+       break;
+    case M_LINK:
+       q.assign (CharConst ("LINK"));
+       break;
+    case M_UNLINK:
+       q.assign (CharConst ("UNLINK"));
+       break;
+    default:
+       assert (0);
+    }
+    q.append (uSPC).append (path);
+    if (fpost) {
        if (formData)
            makeSeparator ();
        if (getparams ()) {
@@ -417,7 +453,7 @@ 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 (fpostdata)
+    if (fpost)
        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);
index 68177b0..7265e74 100644 (file)
@@ -64,8 +64,12 @@ class  HTTPSend {
        HTTP_HEAD,
        HTTP_DONE,
     }  status;
-    bool  fpostdata;
-    ustring  method;
+    bool  fpost;
+//    ustring  method;
+    enum method_t {
+       M_GET, M_HEAD, M_POST, M_OPTIONS, M_PUT, M_DELETE,
+       M_TRACE, M_PATCH, M_LINK, M_UNLINK
+    }  method;
     ustring  proto;
     HostSpec  host;
     ustring  reqhost;
@@ -90,15 +94,28 @@ class  HTTPSend {
     int  responseCode;
 
     HTTPSend () {
+       method = M_GET;
        status = HTTP_INIT;
-       fpostdata = false;
+       fpost = false;
        paramsLen = 0;
        responseCode = 0;
        useproxy = false;
        formData = false;
     };
     virtual  ~HTTPSend () {};
-    virtual void  setMethod (const ustring& _method, bool fpost);
+//    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;
+    };
+    virtual void  setPostFileMethod () {
+       method = M_POST;
+       fpost = true;
+       formData = true;
+    };
     virtual bool  submit (TcpClient& client, TcpBuf& buf, MlEnv* mlenv);
     virtual int  post (TcpClient& client, TcpBuf& buf, ustring& ans, MlEnv* mlenv);
 
index e0e29b2..1121a94 100644 (file)
@@ -330,7 +330,17 @@ MNode*  ml_response_no_cache (MNode* cell, MlEnv* mlenv) {
 
 /*DOC:
 ===$http-get==
- ($http-get [#post] [#sjis] [#file] [:id STRING] [:password STRING | :pw STRING] URL [:query '((NAME . VALUE) ...)] [:cookie '((NAME . VALUE) ...)] [:header '((NAME . VALUE) ...)] [SUBFUNCTION...])
+ ($http-get URL [#get] [#post] [#put] [#delete] [#file]
+       [:id STRING] [:password STRING | :pw STRING]
+       [:query '((NAME . VALUE) ...)] [:get-query '((NAME . VALUE) ...)]
+       [:post-file-serial '((NAME . VALUE) ...)]
+       [:post-file-named '((NAME . VALUE) ...)]
+       [:post-file-static '((NAME . VALUE) ...)]
+       [:cookie '((NAME . VALUE) ...)] [:header '((NAME . VALUE) ...)]
+       [:proxy-host STRING] [:proxy-port NUMBER]
+       [:proxy-id STRING] [:proxy-password STRING | :proxy-pw STRING]
+       [#sjis]
+       [SUBFUNCTION...])
 
 */
 //#MFUNC       $http-get       ml_http_get     cMLHttpGetID
@@ -346,76 +356,82 @@ MNode*  ml_http_get (MNode* cell, MlEnv* mlenv) {
     MNode*  rest;
     MNodePtr  ans;
     static paramList  kwlist[] = {
-       {CharConst ("post"), true}, // 0
-       {CharConst ("id"), false},
-       {CharConst ("password"), false},
-       {CharConst ("pw"), false},
-       {CharConst ("query"), false},
-       {CharConst ("cookie"), false}, // 5
-       {CharConst ("proxy-host"), false},
-       {CharConst ("proxy-port"), false},
-       {CharConst ("proxy-id"), false},
-       {CharConst ("proxy-password"), false},
-       {CharConst ("proxy-pw"), false}, // 10
-       {CharConst ("header"), false},
-       {CharConst ("get-query"), false},
-       {CharConst ("sjis"), true},
-       {CharConst ("file"), true},
-       {CharConst ("post-file-serial"), false}, // 15
-       {CharConst ("post-file-named"), false},
+       {CharConst ("get"), true},      // 0
+       {CharConst ("post"), true},     // 1
+       {CharConst ("put"), true},      // 2
+       {CharConst ("delete"), true},   // 3
+       {CharConst ("file"), true},     // 4
+       {CharConst ("id"), false},      // 5
+       {CharConst ("password"), false}, // 6
+       {CharConst ("pw"), false},      // 7
+       {CharConst ("query"), false},   // 8
+       {CharConst ("get-query"), false},       // 9
+       {CharConst ("post-file-serial"), false}, // 10
+       {CharConst ("post-file-named"), false}, // 11
+       {CharConst ("post-file-static"), false}, // 12
+       {CharConst ("cookie"), false},  // 13
+       {CharConst ("header"), false},  // 14
+       {CharConst ("proxy-host"), false},      // 15
+       {CharConst ("proxy-port"), false},      // 16
+       {CharConst ("proxy-id"), false},        // 17
+       {CharConst ("proxy-password"), false},  // 18
+       {CharConst ("proxy-pw"), false},        // 19
+       {CharConst ("sjis"), true},             // 20
        {NULL, 0, 0}
     };
 
     setParams (arg, 1, &params, kwlist, &keywords, &rest);
     url = eval_str (params[0], mlenv);
     assert (obj.http == NULL);
-    if (keywords[13] && eval_bool (keywords[13], mlenv)) { // sjis
+    if (keywords[20] && eval_bool (keywords[20], mlenv)) // sjis
        obj.http = new HTTPSendIConv ("SHIFT_JIS");
-    } else {
+    else
        obj.http = new HTTPSend;
-    }
-    if (keywords[0] && eval_bool (keywords[0], mlenv)) // post
-       obj.http->setMethod (ustring (CharConst ("POST")), true);
-    if (keywords[1])           // id
-       obj.http->id = omitCtrl (eval_str (keywords[1], mlenv));
-    if (keywords[2])           // password
-       obj.http->pw = omitCtrl (eval_str (keywords[2], mlenv));
-    if (keywords[3])           // pw
-       obj.http->pw = omitCtrl (eval_str (keywords[3], mlenv));
-    if (keywords[4])           // query
-       obj.http->params = eval (keywords[4], mlenv);
-    if (keywords[5])           // cookie
-       cookie = eval (keywords[5], mlenv);
-    if (keywords[6]) {         // proxy-host
+    if (keywords[0] && eval_bool (keywords[0], mlenv)) // get
+       obj.http->setMethod (HTTPSend::M_GET);
+    if (keywords[1] && eval_bool (keywords[1], mlenv)) // post
+       obj.http->setMethod (HTTPSend::M_POST);
+    if (keywords[2] && eval_bool (keywords[2], mlenv)) // put
+       obj.http->setMethod (HTTPSend::M_PUT);
+    if (keywords[3] && eval_bool (keywords[3], mlenv)) // delete
+       obj.http->setMethod (HTTPSend::M_DELETE);
+    if (keywords[4] && eval_bool (keywords[4], mlenv)) // file
+       obj.http->setPostFileMethod ();
+    if (keywords[5])           // id
+       obj.http->id = omitCtrl (eval_str (keywords[5], mlenv));
+    if (keywords[6])           // password
+       obj.http->pw = omitCtrl (eval_str (keywords[6], mlenv));
+    if (keywords[7])           // pw
+       obj.http->pw = omitCtrl (eval_str (keywords[7], mlenv));
+    if (keywords[8])           // query
+       obj.http->params = eval (keywords[8], mlenv);
+    if (keywords[9])           // get-query
+       obj.http->getparams = eval (keywords[9], mlenv);
+    if (keywords[10])          // post-file-serial
+       obj.http->fileparams_store = eval (keywords[10], mlenv);
+    if (keywords[11])          // post-file-named
+       obj.http->fileparams_storage = eval (keywords[11], mlenv);
+    // post-file-static
+    if (keywords[13])          // cookie
+       cookie = eval (keywords[13], mlenv);
+    if (keywords[14])          // header
+       headerquery = eval (keywords[14], mlenv);
+    if (keywords[15]) {                // proxy-host
        MNodePtr  h;
-       h = eval (keywords[6], mlenv);
+       h = eval (keywords[15], mlenv);
        if (! isNil (h ())) {
            obj.http->host.host = omitNonAsciiWord (to_string (h ()));
            obj.http->useproxy = true;
-           if (keywords[7])            // proxy-port
-               obj.http->host.port = to_uint32 (eval_str (keywords[7], mlenv));
-           if (keywords[8])            // proxyid
-               obj.http->proxyid = omitCtrl (eval_str (keywords[8], mlenv));
-           if (keywords[9])            // proxypassword
-               obj.http->proxypw = omitCtrl (eval_str (keywords[9], mlenv));
-           if (keywords[10])           // proxypw
-               obj.http->proxypw = omitCtrl (eval_str (keywords[10], mlenv));
+           if (keywords[16])           // proxy-port
+               obj.http->host.port = to_uint32 (eval_str (keywords[16], mlenv));
+           if (keywords[17])           // proxy-id
+               obj.http->proxyid = omitCtrl (eval_str (keywords[17], mlenv));
+           if (keywords[18])           // proxy-password
+               obj.http->proxypw = omitCtrl (eval_str (keywords[18], mlenv));
+           if (keywords[19])           // proxy-pw
+               obj.http->proxypw = omitCtrl (eval_str (keywords[19], mlenv));
        }
     }
-    if (keywords[11]) {                // header
-       headerquery = eval (keywords[11], mlenv);
-    }
-    if (keywords[12]) {                // get-query
-       obj.http->getparams = eval (keywords[12], mlenv);
-    }
-    if (keywords[14] && eval_bool (keywords[14], mlenv)) { // file
-       obj.http->formData = true;
-       obj.http->setMethod (ustring (CharConst ("POST")), true);
-    }
-    if (keywords[15])          // post-file-serial
-       obj.http->fileparams_store = eval (keywords[15], mlenv);
-    if (keywords[16])          // post-file-named
-       obj.http->fileparams_storage = eval (keywords[16], mlenv);
     
     url_sub (url, obj.http);
     if (obj.http->proto.empty ()) {
diff --git a/modules/ml-security.cc b/modules/ml-security.cc
new file mode 100644 (file)
index 0000000..9394795
--- /dev/null
@@ -0,0 +1,62 @@
+#include "ml-security.h"
+#include "ml.h"
+#include "mlenv.h"
+#include "expr.h"
+#include "util_base64.h"
+#include "util_string.h"
+#include "ustring.h"
+#include <openssl/hmac.h>
+
+
+/*DOC:
+==cryptographic functions
+
+*/
+/*DOC:
+===hmac-sha1===
+ (hmac-sha1 KEY_STRING TEXT [#hex] [#base64]) => STRING
+
+*/
+//#AFUNC       hmac-sha1       ml_hmac_sha1
+MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv) {
+    MNode*  arg = cell->cdr ();
+    ustring  key;
+    ustring  text;
+    enum {
+       ENC_HEX,
+       ENC_BASE64,
+    }  encode = ENC_HEX;
+    ustring  ans;
+    unsigned char  md[EVP_MAX_MD_SIZE];
+    unsigned int  md_len;
+    std::vector<MNode*>  params;
+    std::vector<MNode*>  keywords;
+    static paramList  kwlist[] = {
+       {CharConst ("hex"), true},
+       {CharConst ("base64"), true},
+       {NULL, 0, 0}
+    };
+
+    setParams (arg, 2, &params, kwlist, &keywords, NULL);
+    key = eval_str (params[0], mlenv);
+    text = eval_str (params[1], mlenv);
+    if (keywords[0] && eval_bool (keywords[0], mlenv))
+       encode = ENC_HEX;
+    if (keywords[1] && eval_bool (keywords[1], mlenv))
+       encode = ENC_BASE64;
+
+    HMAC (EVP_sha1 (), key.c_str (), key.length (), uchar_type (text.c_str ()), text.length (), md, &md_len);
+
+    switch (encode) {
+    case ENC_HEX:
+       break;
+    case ENC_BASE64:
+       ans.assign (char_type (md), md_len);
+       ans = base64Encode (ans.begin (), ans.end ());
+       break;
+    default:
+       assert (0);
+    }
+
+    return newMNode_str (new ustring (ans));
+}
diff --git a/modules/ml-security.h b/modules/ml-security.h
new file mode 100644 (file)
index 0000000..4f670d4
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef ML_SECURITY_H
+#define ML_SECURITY_H
+
+#include "ml.h"
+#include "ml-id.h"
+
+class  MNode;
+class  MlEnv;
+
+MNode*  ml_hmac_sha1 (MNode* cell, MlEnv* mlenv);
+
+#endif /* ML_SECURITY_H */