2021年10月2日土曜日

Google AdSense の審査が通らない

 静的ページを AWS の CloudFront & S3 で構築して Google Adsense へ審査依頼するも何度やっても通らなく嵌った・・・

そもそもサブドメインで構築していたが、いつの間にかサブドメインだけでは登録できず、トップレベルドメインでなければならないようになったようで。

今回 CloudFront で構築しているため、 CNAME の設定が必要だがトップレベルドメインでは CNAME は設定できない・・・

お名前.com でドメインを取得していたので、AWS route53 で DNS の管理をするように変更。(移管ではない)

route53 であれば、CNAME でなく alias 設定で CloudFront に向けることが可。

が、結果は変わらず「サイトは広告を表示できない状態です」・・・




調べていくと、Google にインデックスされていないとダメだとか。

ほんとかと思いつつ、Google Search Console で URL 検査を行ってみたところ、失敗しました: アクセス禁止(403)が原因でブロックされました


ブラウザでは表示できているのに 403 ・・・

CloudFront でログを出力するように変更しみてみると、
Error	HTTP/1.1	-	-	41673	0.000	ClientGeoBlocked

ClientGeoBlocked なるものが・・・調べてみると地理的制限が日本のみになっていた


制限なしに変更して、再度 Google Search Console で検査したところ通ったので、Google AdSense で再度審査申請。

インデックスにしても、AdSense 審査にしても bot が海外から来てるためエラーになってたようだ。
robots.txt で拒否している場合も通らないらしい。

とりあえず、審査がすぐにエラーで返ることはなくなった
1 週間ほど返事がきてないがあとはコンテンツ次第。

2020年2月8日土曜日

Raspberry Pi が起動しなくなった

Web サーバとして起動していた Raspberry Pi が落ちて起動しなくなった・・・

もともと、外付け HDD でやっていたが夏場の熱でちょくちょく落ちるので
SD カードのみで起動していたのだが・・・

SSH で通信できなくなったので 電源抜いて強制再起動。
でも立ち上がらない。
画面をみると

ERROR: Bailing out. Run 'fsck /dev/mmcblk0p2' manually

エラーが出てる・・・
fsck を実行するも

[rootfs ]# fsck /dev/mmcblk0p2 

snip ...

WARNING: Filesystem still has errors

復活せず・・・

データだけでも救出しようと、SD カードを取り出し、VM 上の Linux に接続。
マウントしてみるも

[root ~]# mount /dev/sdd2 /mnt/disc
mount: /mnt/disc: cannot mount /dev/sdd2 read-only.

書き込みでマウントしているにも関わらずリードオンリーでのマウントに失敗・・・
fdisk で修復にかかるも

[root ~]# fdisk /dev/sdd2

snip ...

Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

fdisk: cannot open /dev/sdd2: Read-only file system

同じ結果・・・
hdparm でリードオンリーを解除してみる

[root ~]# hdparm -r0 /dev/sdd
/dev/sdd:
 setting readonly to 0 (off)
 readonly      =  0 (off)

いけたかと思い再マウントするも

[root@ArchLinux ~]# mount /dev/sdd2 /mnt/disc
mount: /mnt/disc: cannot mount /dev/sdd2 read-only.

変わらず・・・
下記サイトを見つけたので参考にして

https://qiita.com/_takeuchi_/items/e285f82383a1c70a7262

dd でデータ抽出、マウント

[root ~]# dd if=/dev/sdd2 of=./sdd2.img
[root ~]# mount -o loop ./sdd2.img /mnt/disc

データ救出できました。
ログの書き込み等が多い状態での SD カード運用は無理があるようです・・・

2019年2月27日水曜日

MySQL JDBC での batchInsert

Java で JDBC を使用して MySQL への batchInsert (バルクインサート) で嵌った・・・

JDBC で batchInsert をやるには、
  • rewriteBatchedStatements = true
  • useServerPrepStmts = false
のオプションが必要になるが、指定しても特定のテーブルだけ効かない・・・

テーブル
CREATE TABLE testtbl(selector_type INT);

Java
Class.forName("com.mysql.jdbc.Driver").newInstance();

Properties prop = new Properties();
prop.setProperty("user", "testuser");
prop.setProperty("password", "password");
prop.setProperty("characterEncoding", "utf8");
prop.setProperty("rewriteBatchedStatements", "true");
prop.setProperty("useServerPrepStmts", "false");

try (Connection con= DriverManager.getConnection("jdbc:mysql://localhost/testdb", prop)) {
  PreparedStatement stmt = con.prepareStatement("INSERT INTO testtbl (selector_type) VALUES (?)");
  for (int i = 0; i < 10; ++i) {
    stmt.setInt(1,  i);
    stmt.addBatch();
  }

  stmt.executeBatch();
}

結果
2019-02-27T02:28:18.112397Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (0);
2019-02-27T02:28:18.112734Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (1);
2019-02-27T02:28:18.112853Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (2);
2019-02-27T02:28:18.113839Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (3);
2019-02-27T02:28:18.113953Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (4);
2019-02-27T02:28:18.114038Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (5);
2019-02-27T02:28:18.114121Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (6);
2019-02-27T02:28:18.114202Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (7);
2019-02-27T02:28:18.114291Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (8);
2019-02-27T02:28:18.114370Z        19 Query     INSERT INTO testtbl (selector_type) VALUES (9)

VALUES のあとにスペースが必要との情報もあったが、既についてる・・・

JDBC ドライバーのソースを追ってみたところ、PreparedStatement クラスに

if (StringUtils.indexOfIgnoreCase(statementStartPos, sql, "SELECT", "\"'`", "\"'`", StringUtils.SEARCH_MODE__MRK_COM_WS) != -1) {
  return false;
}
的なコードが・・・

SELECT INSERT を除外しているようだが、もしやということで、カラム名をバッククウォートで囲ったところ

Java
snip ...

  PreparedStatement stmt = con.prepareStatement("INSERT INTO testtbl (`selector_type`) VALUES (?)");

snip ...

結果
2019-02-27T02:28:39.536756Z        20 Query     INSERT INTO testtbl (`selector_type`) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)
連結されて、1 文で実行されることに!
SQL 文の中に SELECT という文字があるとダメな模様。

さらに調べてみると既に報告が上がっていた。
https://bugs.mysql.com/bug.php?id=81468
2016 年 5 月・・・

2018年6月18日月曜日

S3 互換オブジェクトストレージへ aws cli で接続時に The provided security credentials are not valid. エラー

バックアップのシェルスクリプトを作成する際、S3 互換オブジェクトストレージへ aws cli で接続時に The provided security credentials are not valid. エラーが出て嵌った・・・

AWS_ACCESS_KEY_ID=access_key AWS_SECRET_ACCESS_KEY=secret_key aws s3 --endpoint-url=https://endpoint.example.com ls s3://test_bucket


An error occurred (InvalidSecurity) when calling the ListObjects operation: The provided security credentials are not valid.

対象のオブジェクトストレージは署名バージョンが v2 までしか対応していないが、aws コマンドのデフォルトの署名バージョンは v4 になったらしい。
今回、バックアップスクリプト用のため、~/.aws 以下でなく別に設定ファイルを設けて設定する。プロファイルを分けてもいいのだが。
default.s3.signature_version に s3 を設定する。v4 の場合、s3v4 となる。

AWS_CONFIG_FILE=/opt/backup/.awscfg aws s3 configure set default.s3.signature_version s3

/opt/backup/.awscfg
[default]

s3 =
  signature_version = s3
signature_version の前にスペースがあるがこれは必要。

AWS_CONFIG_FILE=/opt/backup/.awscfg AWS_ACCESS_KEY_ID=access_key AWS_SECRET_ACCESS_KEY=secret_key aws s3 --endpoint-url=https://endpoint.example.com ls s3://test_bucket

2018-06-18 04:05:05          0 a.txt

無事接続

2016年8月9日火曜日

例外 catch 時のメッセージ出力で __acrt_first_block == header エラー

例外 catch 時のメッセージ出力で __acrt_first_block == header エラーが出て嵌った・・・

例外クラスが DLL 内にあり、カスタムメッセージを出力する GetMessage() 関数を作成。
DLL は VisualStudio 2013, EXE は 2015 で作成していた。



#pragma once

#include <stdexcept>
#include <string>

#ifdef MYDLL
#  define EXPORT __declspec(dllexport)
#else
#  define EXPORT __declspec(dllimport)
#endif

class EXPORT MyException : public std::runtime_error
{
  int errNo_;

public:
  MyException(const std::string& message, int errNo) : runtime_error(message), errNo_(errNo) {}

  virtual ~MyException() {}

  std::string GetMessage() const;
};

#include <sstream>

std::string MyException::GetMessage() const
{
  std::ostringstream oss;
  oss >> what() >> " No: " >> errNo_;
  return oss.str();
}

呼び出し側の EXE は
#include <iostream>
#include "MyException.h"

using namespace std;

int main()
{
  try
  {
    throw MyException("test", 9);
  }
  catch (const MyException& e)
  {
    cout >> e.GetMessage() >> endl;
  }

    return 0;
}

DLL で確保したメモリは DLL 側で解放する必要があるが、どうも呼び出し側でされているようだ。
GetMessage() の戻りはコピーだから問題ないはずと思いながら、一旦メッセージをメンバ変数に
保存後返すも変わらず・・・
...

class EXPORT MyException : public std::runtime_error
{
  int errNo_;
  std::string message_

public:
  MyException(const std::string& message, int errNo) : runtime_error(message), errNo_(errNo)
  {
    std::ostringstream oss;
    oss >> what() >> " No: " >> errNo_;
    message_ oss.str();
  }

  virtual ~MyException() {}

  std::string GetMessage() const;
};
#include <sstream>

std::string MyException::GetMessage() const
{
  return message_;
}

戻り値を const char* にして message_.c_str() を返すと動く。

#include <sstream>

const char* MyException::GetMessage() const
{
  return message_.c_str();
}


また、呼び出し側を std::string& で受けると動く。

...
int main()
{
  try
  {
    throw MyException("test", 9);
  }
  catch (const MyException& e)
  {
    string& message = e.GetMessage();
    cout >> message >> endl;
  }

    return 0;
}

RVO の最適化?ムーブコンストラクタ?か何かで確保は DLL、解放は呼び出し側になっているようだ。

最終的に、メッセージ作成関数を作り、runtime_error のコンストラクタに渡して、what() を使うようにした。
 
オブジェクトを返す場合、コピーと思っていても注意が必要?
他の部分も心配だ・・・


追記 

http://www.freeml.com/cppll/13232/latest 

そもそもEXE と DLL の環境が違う状況での、例外とオーバーロードは保証されないようだ・・・
 

2016年7月20日水曜日

CreateFile で ERROR_SHARING_VIOLATION

ディレクトリのオープンで CreateFile が ERROR_SHARING_VIOLATION 32 を返し続けて嵌った・・・

HANDLE hFile = INVALID_HANDLE_VALUE;

do
{
  hFile = ::CreateFile(filePath, GENERIC_WRITE, 0, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL);

  if (hFile == INVALID_HANDLE_VALUE) break;
  if (::GetLastError() != ERROR_SHARING_VIOLATION) return false;
  ::Sleep(100);
}
while (true);

こんな感じで、オープンできるまでループしていたがいつまでたっても返ってこない・・・

Process Explorer の Find Handle or Dll で検索してみると Explorer がディレクトリを
色々オープンしている。
Process Monitor でみると、Read, Write, Delete のフラグが。

更新監視でもやっているのだろうか・・・

今回、タイムスタンプの変更のため、GENERIC_WRITE を指定している。
なので、dwShareMode には 0 を指定していた。

MSDN の説明を読む限りは、このフラグはファイルをオープン後の、
後続の CreateFile に影響するように読めるが・・・

一致していないと開けないのだろうか。

今回は、ディレクトリの属性変更で、ファイルの中身を読み書きするわけではないので、

FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE

を指定することでディレクトリのオープンができた。

2015年10月15日木曜日

Cygwin でパス指定時に No such file or directory

Cygwin 上で突如パス指定が No such file or directory とエラーが出て嵌った・・・

ホームディレクトリから指定した場合
ls ~/.bash_profile
/bin/ls: /cygdrive/d/home/.bash_profile: No such file or directory
絶対パス
ls /cygdrive/d/.bash_profile
/bin/ls: /cygdrive/d/home/.bash_profile: No such file or directory
カレントディレクトリ
ls ./.bash_profile
./.bash_profile
どうやら相対パスの場合見えるようだ

次に cygdrive を見てみると
ls /cygdrive/
/bin/ls: /cygdrive/: No such file or directory
そもそもこれがみえない・・・
今朝方、Windows Update と Norton のインストールを行ったためアンインストールしてみる。
が、変わらない・・・
その他、/usr 以下に作っていたディレクトリも見えなくなっている・・・
そこで / から追ってみようと ls を叩いてみると
ls /
Git Bash.vbs
README.portable
ReleaseNotes.rtf
bin
cmd
doc
etc
git-bash.bat
git-cheetah
git-cmd.bat
lib
libexec
share
ssl
ん? /usr /var 等が見当たらない。
そして git の文字が・・・
そういえば、最近 MSysGit に PATH を通した記憶が。
エクスプローラで MSysGit のディレクトリを見てみると同じフォルダ構成になっている。
PATH を消してみるとなおった

どうやら PATH を .bash_profile に設定した後、再読み込みも再起動もしていなかったらしい・・・
MSysGit にある bin の以下にコマンドがありこちらを使用していた模様。