image/bmp

読み込みがバイナリファイルに対応したので、ビットマップファイルをアップロード出来るようにする。

https://wa3.i-3-i.info/word15799.html

action.cで、

レスポンスヘッダのContent-typeでfile_content_typeを出力するようにしているので、バイナリでもなんでも対応できるようになった。

これを選択
これを選択

これを選択。

submitすると
submitすると

submitすると、

画像を表示できた
画像を表示できた

画像を表示できた。

こっちは保存できるんだよなあ・・・。
こっちは保存できるんだよなあ・・・。

こっちは保存できるんだよなあ・・・。

Sample/cgi/Content-type/image_bmp/src/Content-type at master · bg1bgst333/Sample · GitHub

multipart/form-data(boundary)

テキストファイルの場合は、HTTPリクエストボディがNULL文字で切れる事が無いので、boundaryをstrstrで探していたが、バイナリファイルだとそうはいかない。

https://www.ietf.org/rfc/rfc1867.txt

memcmpとfor文で、

探索してる。
今回のHTTPレスポンスボディはファイルの中身だけ。
とはいえ、まだtext/plainのみ対応。

test1.txtを選択
test1.txtを選択

test1.txtを選択。
submitすると、

ファイルだけ返してる
ファイルだけ返してる

ファイルだけ返してる。
ただ、気になるのが、

保存しようとすると、勝手に削除されちゃう。
保存しようとすると、勝手に削除されちゃう。

保存しようとすると、勝手に削除されちゃう。
ウィルス対策なのかな・・・。変なレスポンスでは無いはずだけど・・・。ChromeでもEdgeでも消されちゃう。

Sample/cgi/Content-type/multipart_form-data_boundary/src/Content-type at master · bg1bgst333/Sample · GitHub

multipart/form-data

multipart/form-dataの場合は、どうやってファイルを抽出するかというのが課題となる。

POST - HTTP | MDN

Content-type.htmlは、

これまで通り、enctype="multipart/form-data"。
action.cは、

"CONTENT_TYPE"が"multipart/form-data"かどうかチェック。
その後ろにくっついているboundaryを抽出。
ややこしいのが、その前に2つ"--"を付けたものが実際の区切り線。
リクエストボディを読み込んで、区切り線を見つけたら、今度は"Content-Type"があるかチェック。
Chromeの場合、ファイルの時はこれがあるみたいなのでこうしてるけど、他のブラウザだと違うかも。
その先、2度の連続改行があって、その先からファイルの内容が始まる。
次の区切り線までファイルとして抽出するという感じ。

これでsubmitすると
これでsubmitすると

これでsubmitすると、

このように取り出せる
このように取り出せる

このように取り出せる。
今回はテキストファイルだったので、あえてこの方法で取り出せたけど、おそらくバイナリだと上手くいかない。

Sample/cgi/Content-type/multipart_form-data/src/Content-type at master · bg1bgst333/Sample · GitHub

CONTENT_LENGTH

getenvに"CONTENT_LENGTH"を指定すると、HTTPのBodyのサイズを取得できる。

enqlÌóM

action.cで、

getenvに"CONTENT_LENGTH"を指定すると、ボディサイズが"文字列で"返ってくる。
CONTENT_LENGTH.htmlは、

あまり変わらない。

ファイルを選択してsubmitすると
ファイルを選択してsubmitすると

ファイルを選択してsubmitすると、

このように"Content-length"は214。freadで読み込めたサイズ214と同じ。
このように"Content-length"は214。freadで読み込めたサイズ214と同じ。

このように"Content-length"は214。
freadで読み込めたサイズlen = 214と同じ。

Sample/cgi/CONTENT_LENGTH/CONTENT_LENGTH/src/CONTENT_LENGTH at master · bg1bgst333/Sample · GitHub

CONTENT_TYPE

getenvに"CONTENT_TYPE"を指定すると、"Content-type"を取得できる。

c++でcgi ー ファイルのアップロード ~ プログラムのメモ

action.cで、

getenvに"CONTENT_TYPE"を指定し、返ってきた文字列を出力。
CONTENT_TYPE.htmlは、

ファイルだけ送る。

ファイルを選択してsubmit
ファイルを選択してsubmit

ファイルを選択してsubmitすると、

Content-typeは”multipart/form-data”になってる。
Content-typeは”multipart/form-data”になってる。

Content-typeは”multipart/form-data”になってる。

Sample/cgi/CONTENT_TYPE/CONTENT_TYPE/src/CONTENT_TYPE at master · bg1bgst333/Sample · GitHub

form#enctype(application/x-www-form-urlencoded)

enctype属性を指定しない場合は、デフォルトで"application/x-www-form-urlencoded"になる。

HTMLタグ/フォームタグ/送信時のデータ形式を指定する - TAG index

form.htmlで、

<html>
  <head>
    <title>form#enctype#application/x-www-form-urlencoded</title>
  </head>
  <body>
    <script type="text/javascript">
    <!--
    // -->
    </script>
    <form method="GET" action="/cgi-bin/action.cgi" enctype="application/x-www-form-urlencoded">
      <input type="text" name="key1">
      <input type="text" name="key2">
      <input type="submit" value="submit">
    </form>
  </body>
</html>

今回はmethodを"GET"にして、enctypeに敢えて"application/x-www-form-urlencoded"を指定してみる。

日本語テキストを入力
日本語テキストを入力

日本語テキストを入力。
これでsubmitすると、

GETなのでクエリ文字列がURLエンコードされてる
GETなのでクエリ文字列がURLエンコードされてる

GETなのでクエリ文字列がURLエンコードされてる。
enctypeがなくても同じ。
(URLバーが日本語のままなのはChromeの仕様かな。)

今度は"POST"で、

日本語テキストを入力
日本語テキストを入力

日本語テキストを入力。
これでsubmitすると、

今度はHTTPのBodyのほうがURLエンコード
今度はHTTPのBodyのほうがURLエンコード

今度はHTTPのBodyのほうがURLエンコードされてる。
これもenctypeがなくても同じ。

Sample/html/form/enctype_application_x_www_form_urlencoded/src/form at master · bg1bgst333/Sample · GitHub

form#enctype(multipart/form-data)

multipart/form-dataは、その名の通り、複数のパートに分けられているので、ファイル以外にテキストなどのデータも送れる。

<form> - フォーム - とほほのWWW入門

form.htmlで、

前後にテキスト入力フォームを挟むと、

こうなる。そして既にファイルも選択しておく。
こうなる。そして既にファイルも選択しておく。

こうなる。そして既にファイルも選択しておく。
この状態でsubmitすると、

テキストもファイルも複数のパートに分かれて送られている
テキストもファイルも複数のパートに分かれて送られている

テキストもファイルも複数のパートに分かれて送られている。

Sample/html/form/enctype_multipart_form_data/src/form at master · bg1bgst333/Sample · GitHub