Content-Type

Content-Typeにコンテンツ形式を指定する。

Content-Type - HTTP | MDN

http_server.cで、

    /* 書き込み */
    strcpy(send_buf, "HTTP/1.0 200 OK\r\n"); /* send_bufに"HTTP/1.0 200 OK\r\n"をコピー. */
    strcat(send_buf, "Content-Length: 144\r\n"); /* send_bufに"Content-Length: 144\r\n"を連結. */
    strcat(send_buf, "Content-Type: text/plain\r\n"); /* send_bufに"Content-Type: text/plain\r\n"を連結. */
    strcat(send_buf, "\r\n"); /* send_bufに"\r\n"を連結. */
    strcat(send_buf, "<html>\r\n"); /* send_bufに"<hmtl>\r\n"を連結. */
    strcat(send_buf, "  <head>\r\n"); /* send_bufに"  <head>\r\n"を連結. */
    strcat(send_buf, "    <title>Content-Type</title>\r\n"); /* send_bufに"    <title>Content-Type</title>\r\n"を連結. */
    strcat(send_buf, "  </head>\r\n"); /* send_bufに"  </head>\r\n"を連結. */
    strcat(send_buf, "  <body>\r\n"); /* send_bufに"  <body>\r\n"を連結. */
    strcat(send_buf, "    <a href=\"http://bgstation0.com/\">B.G-STATION</a>\r\n"); /* send_bufに"    <a href=\"http://bgstation0.com/\">B.G-STATION</a>\r\n"を連結. */
    strcat(send_buf, "  </body>\r\n"); /* send_bufに"  </body>\r\n"を連結. */
    strcat(send_buf, "</html>\r\n"); /* send_bufに"</html>\r\n"を連結. */
    send(acc, send_buf, strlen(send_buf), 0); /* send_bufを送信. */

text/plainにした場合、

テキストで表示される
テキストで表示される

テキストで表示される。

text/plainになっている
text/plainになっている

text/plainになっている。

text/htmlにすると、

HTMLのリンクになってる
HTMLのリンクになってる

HTMLのリンクになってる。

text/htmlになってる
text/htmlになってる

text/htmlになってる。
HTMLなんだから、リンクをクリックすると、

リンク先に飛ぶ
リンク先に飛ぶ

リンク先に飛ぶ。

Sample/http/Content-Type/Content-Type/src/Content-Type at master · bg1bgst333/Sample · GitHub

Content-Length

通常はHTTPレスポンスヘッダのContent-LengthにHTTPレスポンスボディの長さ(バイト数)を指定する。

Content-Length - HTTP | MDN

http_server.cで、

"ABCDE"をボディとするので、Content-Lengthは5。
ヘッダとボディの間には空行を入れる。

&quot;ABCDE&quot;が表示される。
"ABCDE"が表示される。

"ABCDE"が表示される。

Content-Lengthがちゃんと返されてる。
Content-Lengthがちゃんと返されてる。

Content-Lengthがちゃんと返されてる。

Sample/http/Content-Length/Content-Length/src/Content-Length at master · bg1bgst333/Sample · GitHub

HTTPステータスコード

以前から"ネットワーク"カテゴリをやろうと思ってたが、プロトコル個別の方が良いかなとおもって、"HTTP"カテゴリにした。
まずはHTTPステータスコードだけを返すサーバを作ってみた。

HTTP | MDN
HTTP レスポンスステータスコード - HTTP | MDN

http_server.cで、

と一気に書いてみた。
いろいろあるけど、特定ポート指定でブラウザ接続してきたら、"HTTP/1.0 200 OK\r\n"を返すだけとシンプル。

3001ポートで待ち受け
3001ポートで待ち受け

3001ポートで待ち受け。

アクセスすると真っ白
アクセスすると真っ白

アクセスすると真っ白。
でもアクセスできませんでしたとかではない。

デベロッパーツールを出してリロードする
デベロッパーツールを出してリロードする

デベロッパーツールを出してリロードする。

こんな感じでリクエスト来てる
こんな感じでリクエスト来てる

こんな感じでリクエスト来てる。
上が"/"で、下がfavicon.icoか。

最低限のバージョンとステータスコードとメッセージだけを返してもこうなる
最低限のバージョンとステータスコードとメッセージだけを返してもこうなる

最低限のバージョンとステータスコードとメッセージだけを返してもこうなる。
ちゃんと認識してる。

Sample/http/http_status_code/http_status_code/src/http_status_code at master · bg1bgst333/Sample · GitHub

strcoll

strcollは、ロケールのLC_COLLATEに従って文字列の順序を判定(そのロケールの辞書順)する。

Man page of STRCOLL
strcoll - cppreference.com

ロケールによっては、アルファベット順ではない場合があるらしい。
strcoll.cで、

チェコ語では、"ch"よりも"h"が前らしい。

$ vi strcoll.c
$ gcc strcoll.c -o strcoll
$ ./strcoll
ch, h
ch, h
ch, h
h, ch
$

ロケールチェコにして、strcollを呼んだ時だけ, "h"の後に"ch"が来る。
ハンガリー語スペイン語などもアルファベット順が辞書順ではないみたい。
日本語がどうなのか(あいうえお順なのかとか。)は試してない。

Sample/c/strcoll/strcoll/src/strcoll at master · bg1bgst333/Sample · GitHub

strtol

strtolは、文字列を指定された基数で変換(n進数の文字列だと解釈)する。

Man page of STRTOL
strtol, strtoll - cppreference.com

strtol.cで、

与えられた文字列を0, 2, 8, 10, 16を基数として変換。

$ vi strtol.c
$ gcc strtol.c -o strtol
$ ./strtol
str: 1010
l_0 = 1010
l_2 = 10
l_8 = 520
l_10 = 1010
l_16 = 4112

"1010"を試す。
0を基数は自動検出。10進数の1010として見てるのかな。
2を基数とすると、8 + 2だから10進数の10。
8を基数とすると、512 + 8だから10進数の520。
10を基数は、0を基数とする場合と同じ。
16を基数とすると、4096 + 16だから10進数の4112。

$ ./strtol
str: 9
l_0 = 9
l_2 = 0
l_8 = 0
l_10 = 9
l_16 = 9

9は10進数、16進数にしかないので、他は0。

$ ./strtol
str: a
l_0 = 0
l_2 = 0
l_8 = 0
l_10 = 0
l_16 = 10

aは16進数にしかないので、他は0。

$ ./strtol
str: 0xc
l_0 = 12
l_2 = 0
l_8 = 0
l_10 = 0
l_16 = 12

cもそうだけど、"0x"を付けてるので基数0の場合の自動検出でも変換できた。

$ ./strtol
str: 022
l_0 = 18
l_2 = 0
l_8 = 18
l_10 = 22
l_16 = 34
$

"0"を付けてるので、8進数で解釈すれば18。
ただ、10進数や16進数でも解釈できるのでそれだとそれぞれ、22、34と解釈される。

Sample/c/strtol/strtol/src/strtol at master · bg1bgst333/Sample · GitHub

atof

atofは、実数の文字列を倍精度浮動小数点数値型に変換する。

Man page of ATOF

atof.cで、

入力文字列がどうなるか試してみる。

$ vi atof.c
$ gcc atof.c -o atof
$ ./atof
str: 1
d = 1.000000
$ ./atof
str: 1.23
d = 1.230000
$ ./atof
str: -4.56
d = -4.560000
$ ./atof
str: 1.23abc
d = 1.230000
$ ./atof
str: 1.2e3
d = 1200.000000
$ ./atof
str: 1.2e+3
d = 1200.000000
$ ./atof
str: 1.2e-3
d = 0.001200
$ ./atof
str: 1.2ee3
d = 1.200000
$ ./atof
str: 0xff
d = 255.000000
$ ./atof
str: -0xff
d = -255.000000
$

整数でも実数でもマイナスでも対応。
途中から文字列と判断すればカット。
しかしeを用いた指数表現には対応。
16進数も対応。

Sample/c/atof/atof/src/atof at master · bg1bgst333/Sample · GitHub

ispunct

ispunctは、句読点文字かどうかをチェックする。

ispunct(3) manページ

句読点文字というのは区切り文字の事だが、実態としては英数字を除いた表示可能文字、つまり記号であり、スペースは含まれない。

いろいろな文字で試してみる。

$ vi ispunct.c
$ gcc ispunct.c -o ispunct
$ ./ispunct
.
2e is Punctuation Character!
$ ./ispunct
,
2c is Punctuation Character!
$ ./ispunct
;
3b is Punctuation Character!
$ ./ispunct
(
28 is Punctuation Character!
$ ./ispunct
+
2b is Punctuation Character!
$ ./ispunct
?
3f is Punctuation Character!
$ ./ispunct
a
$ ./ispunct
1
$ ./ispunct

$

ドット、カンマ、セミコロンなどの区切り文字は真になる。
それどころか、括弧、プラス、はてなも真になる。
一方で、a、1などの英数字は偽であり、スペースも偽となる。

Sample/c/ispunct/ispunct/src/ispunct at master · bg1bgst333/Sample · GitHub