Help us understand the problem. What is going on with this article?

Redmine REST-APIを利用してcurlからチケット作成

環境

以下、RedmineのURLを http://127.0.0.1/redmine/ とする。

Redmine REST-API有効化

  1. プロジェクトを作成する
  2. 管理->設定->API1->RESTによるWebサービスを有効にするにチェックを入れる

プロジェクトを作成しなくてもREST-APIは有効化できる。
チケットを作成するためにはプロジェクトが必要なので、なければ作っておく。

APIアクセスキー取得

  1. アカウントを作成する
  2. 個人設定2->APIアクセスキー->表示3

既存のアカウントがあればそちらを使用。
APIキーは7de23362bf2dfc965dec1413d72bf8daf337681bのような16進数(?)の羅列となっている。

チケット作成

curl -X POST -H "Content-Type: application/json" -H "X-Redmine-API-Key: 7de23362bf2dfc965dec1413d72bf8daf337681b" -d @issue_test.json http://127.0.0.1/redmine/issues.json
issue_test.json
{
    "issue": {
        "project_id": 1,
        "subject": "test1",
        "tracker_id": 1,
        "description": "message"
    }
}
response

画像のアップロード

アップロードするファイルのパスの先頭に@を付けることを忘れないこと。--data-binary @image.png部分のこと。
Content-Type: image/pngの方が正しいように思えるが成功しなかった。4

curl -X POST -H "Content-Type: application/octet-stream" -H "X-Redmine-API-Key: 7de23362bf2dfc965dec1413d72bf8daf337681b" -H "Expect:" --data-binary @image.png http://127.0.0.1/redmine/uploads.json?filename=image.png
response

アップロードに成功したファイルはブラウザでhttp://127.0.0.1/redmine/attachments/5を開くと確認できる。末尾の5はレスポンスに含まれるid値に置き換えること。
アップロード時のURL指定(uploads.json?filename=image.png)のfilenameの指定を忘れるとファイル名がハッシュ値(?)になる。画像のプレビューはできなくなる。

Expectヘッダ

-H "Expect:"を指定しない場合、以下のようなログが出て失敗した。

error-log
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> POST /redmine/uploads.json HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.55.1
> Accept: */*
> Content-Type: application/octet-stream
> X-Redmine-API-Key: 7de23362bf2dfc965dec1413d72bf8daf337681b
> Content-Length: 2717
> Expect: 100-continue
>
* Done waiting for 100-continue
* We are completely uploaded and fine
< HTTP/1.1 502 Proxy Error
< Date: Fri, 29 May 2020 14:19:58 GMT
< Server: Apache
< X-Frame-Options: SAMEORIGIN
< Content-Length: 341
< Connection: close
< Content-Type: text/html; charset=iso-8859-1
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>502 Proxy Error</title>
</head><body>
<h1>Proxy Error</h1>
<p>The proxy server received an invalid
response from an upstream server.<br />
The proxy server could not handle the request<p>Reason: <strong>Error reading from remote server</strong></p></p>
</body></html>
* Closing connection 0

curl の Expect: 100-continue を抑制する - 氾濫原
curl は POST や PUT でリクエストボディの長さが長いなどの特定条件になると、まず Expect: 100-continue をつけてリクエストを送り、サーバ側の対応を待ってからリクエストボディを改めて送るという行儀が良い実装になっている。

しかし、特に IoT っぽい機器では Expect: 100-continue に対応していないものもあるので、抑制したい場合がでてくる。そういうときは以下のようにする。

curl -H "Expect:" -d ... url

空の Expect ヘッダを指定することで上記のような挙動をしなくなり、最初からリクエストをフルで送りつけるようになる。

チケットへの画像添付

tokenの値は画像アップロード時のレスポンスに含まれている。
uploadsは配列であることに注意。

curl -X POST -H "Content-Type: application/json" -H "X-Redmine-API-Key: 7de23362bf2dfc965dec1413d72bf8daf337681b" -d @redmine_attach.json http://127.0.0.1/redmine/issues.json
redmine_attach.json
{
    "issue": {
        "project_id": 1,
        "subject": "test1",
        "tracker_id": 1,
        "description": "message",
        "uploads": [
            {
                "token": "10.dc2d8a87ce35ced5892bd5a68adaf82e9a6cf1d51bfb4afeae813980ccd44a1c",
                "filename": "image.png",
                "content_type": "image/png"
            }
        ]
    }
}
response

TIPS

Proxyを無効にする

--proxy ""

--proxy ""

または

-x ""

--no-proxy

特定IP(ホスト)のみ無効

--no-proxy "127.0.0.1"

ポート番号まで指定しないとうまく行かないことがあった。

--no-proxy "127.0.0.1:80"

参考

huging
知識を蓄積します
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away