my @ID;
my @SRCS;
+my $target = "ml-id.h";
+my $targetTmp = "$target-$$";
open (IN, "../Makefile.conf");
while (<IN>) {
}
}
-open (OUT, "> ml-id.h");
+open (OUT, "> $targetTmp");
print OUT "#ifndef ML_ID_H\n";
print OUT "#define ML_ID_H\n\n";
my $c = 0;
print OUT "\n#endif /* ML_ID_H */\n";
close (OUT);
+if (-f $target && ! cmpFile ($target, $targetTmp)) {
+ unlink ($targetTmp);
+} else {
+ rename ($targetTmp, $target);
+ print "$target\n";
+}
+
exit;
sub p {
}
$sum;
}
+
+sub cmpFile {
+ my ($f1, $f2) = @_;
+ my ($rc);
+
+ $rc = system ('/usr/bin/cmp', '-s', $f1, $f2) >> 8;
+ return $rc;
+}
my @WFN;
my @HDR;
my @SRCS;
+my $target = "ftable.cc";
+my $targetTmp = "$target-$$";
open (IN, "../Makefile.conf");
while (<IN>) {
}
}
-open (OUT, "> ftable.cc");
+open (OUT, "> $targetTmp");
print OUT "#include \"ftable.h\"\n";
print OUT "#include \"mftable.h\"\n";
foreach (@HDR) {
&wikiftable;
close (OUT);
+if (-f $target && ! cmpFile ($target, $targetTmp)) {
+ unlink ($targetTmp);
+} else {
+ rename ($targetTmp, $target);
+ print "$target\n";
+}
+
exit;
sub p {
print OUT "FTable GWikiFTable (wikiftable);\n";
}
+
+sub cmpFile {
+ my ($f1, $f2) = @_;
+ my ($rc);
+
+ $rc = system ('/usr/bin/cmp', '-s', $f1, $f2) >> 8;
+ return $rc;
+}
my @FN2;
my @HDR;
my @SRCS;
+my $target = "wikitable.cc";
+my $targetTmp = "$target-$$";
opendir (DIR, "../wiki");
@a = readdir (DIR);
&p ($_);
}
-open (OUT, "> wikitable.cc");
+open (OUT, "> $targetTmp");
print OUT "#include \"wikitable.h\"\n";
foreach (@HDR) {
print OUT "#include \"$_\"\n";
print OUT "//============================================================\n";
close (OUT);
+if (-f $target && ! cmpFile ($target, $targetTmp)) {
+ unlink ($targetTmp);
+} else {
+ rename ($targetTmp, $target);
+ print "$target\n";
+}
+
exit;
sub p {
}
}
}
+
+sub cmpFile {
+ my ($f1, $f2) = @_;
+ my ($rc);
+
+ $rc = system ('/usr/bin/cmp', '-s', $f1, $f2) >> 8;
+ return $rc;
+}
int HTTPSend::readReplyHead (TcpClient& client, TcpBuf& buf) {
ustring line;
bool rc;
- uiterator b, e;
+ uiterator b, e, m1, m2;
if (status != HTTP_QUERY)
return 0;
break;
b = line.begin ();
e = line.end ();
- if (matchSkip (b, e, CharConst ("Set-Cookie:"))) {
- skipSpace (b, e);
- readCookie (b, e);
- } else {
+ if (splitChar (b, e, ':', m1)) {
+ ustring s;
+ m2 = m1 + 1;
+ skipSpace (m2, e);
+// toLower ((ustring::iterator*)&b, (ustring::iterator*)&m1);
+ s = toLower (b, m1);
+ header_reply.push_back (mapelem (s, ustring (m2, e)));
+ if (match (s, CharConst ("set-cookie"))) {
+ readCookie (m2, e);
+ }
}
}
status = HTTP_HEAD;
return responseCode;
}
-void HTTPSend::readReplyBody (TcpClient& client, TcpBuf& buf, ustring& ans) {
+void HTTPSend::readReplyBody (TcpClient& client, TcpBuf& buf, MotorOutput* out) {
if (status != HTTP_HEAD)
return;
- ans.assign (buf.start, buf.tail);
+ out->out (buf.start, buf.tail);
buf.consume ();
while (buf.fill (client)) {
- ans.append (buf.start, buf.tail);
+ out->out (buf.start, buf.tail);
buf.consume ();
}
status = HTTP_DONE;
}
-void HTTPSend::readReplyBody (TcpClient& client, TcpBuf& buf, std::ostream& out) {
- if (status != HTTP_HEAD)
- return;
+void HTTPSend::readReplyBody (TcpClient& client, TcpBuf& buf, ustring& ans) {
+ std::stringstream ostr;
+ MotorOutputOStream out (&ostr);
+ readReplyBody (client, buf, &out);
+ ans = ostr.str ();
+}
- out << ustring (buf.start, buf.tail);
- buf.consume ();
- while (buf.fill (client)) {
- out << ustring (buf.start, buf.tail);
- buf.consume ();
+const ustring* HTTPSend::findHeader (const ustring& name) {
+ std::vector<mapelem>::const_iterator b = header_reply.begin ();
+ std::vector<mapelem>::const_iterator e = header_reply.end ();
+
+ for (; b < e; b ++) {
+ if (b->first == name) {
+ return &b->second;
+ }
}
- status = HTTP_DONE;
+ return NULL;
}
void HTTPSend::readCookie (uiterator b, uiterator e) {
std::vector<ustring> ary;
- ustring::size_type ix;
- uiterator it, ie;
+ uiterator ib, ie, im;
static uregex re ("; *");
split (b, e, re, ary);
if (ary.size () > 0) {
CookieInfo ci;
- it = ary[0].begin ();
+ ib = ary[0].begin ();
ie = ary[0].end ();
- ix = ary[0].find ('=', 0);
- if (ix == ustring::npos) {
- ci.key = ary[0];
+ if (splitChar (ib, ie, '=', im)) {
+ ci.key.assign (ib, im);
+ ci.value.assign (im + 1, ie);
} else {
- ci.key.assign (it, it + ix);
- ci.value.assign (it + ix + 1, ie);
+ ci.key.assign (ib, ie);
}
- cookie_get.push_back (ci);
+ cookie_reply.push_back (ci);
}
}
class HTTPSend {
public:
+ typedef std::pair<ustring,ustring> mapelem;
+
enum {
HTTP_INIT,
HTTP_OPEN,
ustring id;
ustring pw;
ustring cookie;
- std::vector<CookieInfo> cookie_get;
+ std::vector<mapelem> header_reply;
+ std::vector<CookieInfo> cookie_reply;
int responseCode;
HTTPSend () {
virtual ustring query ();
virtual int readReplyHead (TcpClient& client, TcpBuf& buf);
+ virtual void readReplyBody (TcpClient& client, TcpBuf& buf, MotorOutput* out);
virtual void readReplyBody (TcpClient& client, TcpBuf& buf, ustring& ans);
- virtual void readReplyBody (TcpClient& client, TcpBuf& buf, std::ostream& out);
+ virtual const ustring* findHeader (const ustring& name);
+ private:
virtual void readCookie (uiterator b, uiterator e);
};
#include <boost/lexical_cast.hpp>
#include <iostream>
-using namespace std;
-
/* ============================================================ */
static uregex re_encode ("(<)|(>)|(&)|(\")|(')");
static uregex re_encode_br ("(<)|(>)|(&)|(\")|(')|(\n)");
}
/* ============================================================ */
-MotorOutput* MotorOutputOStream::out (const ustring::value_type* s, size_t len) {
- cout.write (s, len);
+MotorOutput* MotorOutputCOut::out (const ustring::value_type* s, size_t len) {
+ std::cout.write (s, len);
return this;
}
}
/* ============================================================ */
+MotorOutput* MotorOutputOStream::out (const ustring::value_type* s, size_t len) {
+ ostream->write (s, len);
+ return this;
+}
+
+/* ============================================================ */
static void format_hex (ustring& ans, MNode* a, std::vector<ustring>& par, bool fcap) {
uint32_t v = 0;
char buf[32];
}
};
-class MotorOutputOStream: public MotorOutput {
+class MotorOutputCOut: public MotorOutput {
public:
- MotorOutputOStream () {};
- virtual ~MotorOutputOStream () {};
+ MotorOutputCOut () {};
+ virtual ~MotorOutputCOut () {};
virtual MotorOutput* out (const ustring::value_type* s, size_t len);
};
};
};
+class MotorOutputOStream: public MotorOutput {
+ public:
+ std::ostream* ostream;
+
+ MotorOutputOStream (std::ostream* _ostream): ostream (_ostream) {};
+ virtual ~MotorOutputOStream () {};
+
+ virtual MotorOutput* out (const ustring::value_type* s, size_t len);
+};
+
class MNodePtr;
ustring outamp (const ustring& t);
ustring outamp_br (const ustring& t);
#include <boost/regex.hpp>
#include <iconv.h>
#include <vector>
+#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
}
}
-/*
-bool splitChar (uiterator b, uiterator e, uiterator::value_type ch, uiterator& m1, uiterator& m2) {
+bool splitChar (uiterator b, uiterator e, uiterator::value_type ch, uiterator& m1) {
for (; b < e; b ++) {
if (*b == ch) {
- m2 = m1 = b;
- m2 ++;
+ m1 = b;
return true;
}
}
- m1 = m2 = e;
+ m1 = e;
return false;
}
-*/
static char Base64Char[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
ustring base64Encode (uiterator b, uiterator e) {
b ++;
}
}
+
+static ustring::value_type toLower_ustring_value (ustring::value_type v) {
+ if ('A' <= v && v <= 'Z') {
+ return v - 'A' + 'a';
+ } else {
+ return v;
+ }
+}
+
+#if 0
+void toLower (ustring::iterator* b, ustring::iterator* e) {
+ transform (*b, *e, *b, toLower_ustring_value);
+}
+#endif
+
+ustring toLower (uiterator b, uiterator e) {
+ ustring::iterator i;
+ ustring ans;
+ ans.resize (e - b);
+ i = ans.begin ();
+ for (; b < e; b ++, i++) {
+ *i = toLower_ustring_value (*b);
+ }
+ return ans;
+}
ustring dirPart (const ustring& path);
ustring filePart_osSafe (const ustring& path);
void split (uiterator b, uiterator e, uregex& re, std::vector<ustring>& ans);
-//bool splitChar (uiterator& b, uiterator& e, uiterator::value_type ch, uiterator& m1, uiterator& m2);
+bool splitChar (uiterator b, uiterator e, uiterator::value_type ch, uiterator& m1);
ustring base64Encode (uiterator b, uiterator e);
ustring filenameEncode (const ustring& text);
ustring escape_re (const ustring& text);
uint32_t hextoul (uiterator b, uiterator e);
ustring toCRLF (const ustring& str);
void skipSpace (uiterator& b, uiterator e);
+ustring toLower (uiterator b, uiterator e);
#endif /* UTIL_STRING_H */
ustring::iterator tail;
TcpBuf () {
-// buf.assign (65536, '\0');
- buf.assign (256, 0);
+ buf.assign (65536, '\0');
+// buf.assign (256, 0);
start = tail = buf.begin ();
};
virtual ~TcpBuf () {};
../bin/MKWTABLE.pl
../bin/MKID.pl
-ftable.cc: ${MSRCS}
+ftable.cc: ${MSRCS} ../Makefile.conf
#ftable.cc:
../bin/MKTABLE.pl
#wikitable.cc:
../bin/MKWTABLE.pl
-ml-id.h: ${MSRCS}
+ml-id.h: ${MSRCS} ../Makefile.conf
#ml-id.h:
../bin/MKID.pl
} else {
// form = new CGIFormUTF8;
form = new CGIFormUTF8JPMS;
- out = new MotorOutputOStream;
+ out = new MotorOutputCOut;
}
#else
form = new CGIFormUTF8;
Ex1:;
delete out;
delete form;
+
+ return 0;
}
#include "ml.h"
#include "mlenv.h"
#include "motorenv.h"
+#include "motoroutput.h"
#include "util_check.h"
#include "util_string.h"
#include "http.h"
tgt = mlenv->env->path_store_file (name);
tmp.assign (tgt).append (CharConst ("-tmp")).append (boost::lexical_cast<ustring> (getpid ()));
{
- std::ofstream out;
- out.open (tmp.c_str (), std::ios_base::out | std::ios_base::binary);
- obj->http.readReplyBody (obj->client, obj->buf, out);
- out.close ();
+ std::ofstream stream;
+ MotorOutputOStream out (&stream);
+ stream.open (tmp.c_str (), std::ios_base::out | std::ios_base::binary);
+ obj->http.readReplyBody (obj->client, obj->buf, &out);
+ stream.close ();
rename (tmp.c_str (), tgt.c_str ());
}
MNode* arg = cell->cdr ();
MLHttpGet* obj = (MLHttpGet*)mobj;
- obj->http.readReplyBody (obj->client, obj->buf, std::cout);
+// obj->http.readReplyBody (obj->client, obj->buf, std::cout);
+ obj->http.readReplyBody (obj->client, obj->buf, mlenv->env->output);
return NULL;
}
if (arg)
throw (uErrorWrongNumber);
- for (i = 0; i < obj->http.cookie_get.size (); i ++) {
- if (obj->http.cookie_get[i].key == name) {
- return newMNode_str (new ustring (obj->http.cookie_get[i].value));
+ for (i = 0; i < obj->http.cookie_reply.size (); i ++) {
+ if (obj->http.cookie_reply[i].key == name) {
+ return newMNode_str (new ustring (obj->http.cookie_reply[i].value));
}
}
if (arg)
throw (uErrorWrongNumber);
- for (i = 0; i < obj->http.cookie_get.size (); i ++) {
+ for (i = 0; i < obj->http.cookie_reply.size (); i ++) {
a = new MNode;
- a->set_car (newMNode_str (new ustring (obj->http.cookie_get[i].key)));
+ a->set_car (newMNode_str (new ustring (obj->http.cookie_reply[i].key)));
a->set_cdr (new MNode);
- a->cdr ()->set_car (newMNode_str (new ustring (obj->http.cookie_get[i].value)));
+ a->cdr ()->set_car (newMNode_str (new ustring (obj->http.cookie_reply[i].value)));
ans.append (a);
}
return ans.release ();
}
+
+/*DOC:
+====http-content-type====
+ (http-content-type) -> STRING
+
+*/
+//#SFUNC http-content-type ml_http_content_type
+MNode* ml_http_content_type (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
+ MNode* arg = cell->cdr ();
+ MLHttpGet* obj = (MLHttpGet*)mobj;
+ const ustring* u;
+ static ustring name (CharConst ("content-type"));
+
+ u = obj->http.findHeader (name);
+ if (u) {
+ uiterator b, e, m;
+ b = u->begin ();
+ e = u->end ();
+ if (splitChar (b, e, ';', m)) {
+ return newMNode_str (new ustring (toLower (b, m)));
+ } else {
+ return newMNode_str (new ustring (toLower (b, e)));
+ }
+ } else {
+ return NULL;
+ }
+
+#if 0
+ std::vector<std::pair<ustring,ustring> >::const_iterator t, e;
+
+ t = obj->http.header_reply.begin ();
+ e = obj->http.header_reply.end ();
+ for (; t < e; t ++) {
+ if (match (t->first, CharConst ("content-type"))) {
+ uiterator b, e, m;
+ b = t->second.begin ();
+ e = t->second.end ();
+ if (splitChar (b, e, ';', m)) {
+ return newMNode_str (new ustring (toLower_copy (b, m)));
+ } else {
+ return newMNode_str (new ustring (toLower_copy (b, e)));
+ }
+ }
+ }
+ return NULL;
+#endif
+}
+
+/*DOC:
+====http-get-header====
+ (http-get-header NAME) -> STRING
+
+*/
+//#SFUNC http-get-header ml_http_get_header
+MNode* ml_http_get_header (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
+ MNode* arg = cell->cdr ();
+ MLHttpGet* obj = (MLHttpGet*)mobj;
+ ustring name;
+ const ustring* u;
+
+ if (! arg)
+ throw (uErrorWrongNumber);
+ name = eval_str (arg->car (), mlenv);
+ nextNode (arg);
+ if (arg)
+ throw (uErrorWrongNumber);
+
+ name = toLower (name.begin (), name.end ());
+ u = obj->http.findHeader (name);
+ if (u) {
+ return newMNode_str (new ustring (*u));
+ } else {
+ return NULL;
+ }
+}
MNode* ml_http_get_http_response_output (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
MNode* ml_http_get_get_cookie (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
MNode* ml_http_get_get_cookie_all (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
+MNode* ml_http_content_type (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
+MNode* ml_http_get_header (MNode* cell, MlEnv* mlenv, MLFunc* mobj);
#endif /* ML_HTTP_H */
if (! mlenv->env->responseDone)
mlenv->env->standardResponse (ustring (CharConst (kMIME_XML)), ustring (CharConst (kCODE_UTF8)));
- MotorOutputOStream out;
+ MotorOutputCOut out;
out.out (CharConst ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"));
xmlWrite (&out, xml ());