Goについて扱うスレッドです。
GoはGoogleによって開発された言語です。
公式ドキュメント
http://golang.org/doc/
日本語訳
http://golang.jp
※前スレ
Go language part 2
https://mevius.5ch.net/test/read.cgi/tech/1510395926/
Go language part 3
■ このスレッドは過去ログ倉庫に格納されています
2019/10/17(木) 21:38:04.78ID:wMsZ+t6y
453デフォルトの名無しさん
2020/05/01(金) 11:36:26.80ID:txiwXjh+ 各プラットフォームのランタイムのせいだろうとは思うけど・・・
io パッケージの
func Copy(dst Writer, src Reader) (written int64, err error)
と
type Writer interface {
Write(p []byte) (n int, err error)
}
で戻り値に一貫性がない事に気づいて、ちょっとイラっときた
(io.Writer).Write() では n の合計が len(p) になるまで繰り返さないとダメ?
かと思ったけど、
Write must return a non-nil error if it returns n < len(p).
って書いてあるよ・・・
io パッケージの
func Copy(dst Writer, src Reader) (written int64, err error)
と
type Writer interface {
Write(p []byte) (n int, err error)
}
で戻り値に一貫性がない事に気づいて、ちょっとイラっときた
(io.Writer).Write() では n の合計が len(p) になるまで繰り返さないとダメ?
かと思ったけど、
Write must return a non-nil error if it returns n < len(p).
って書いてあるよ・・・
454デフォルトの名無しさん
2020/05/01(金) 11:43:36.06ID:txiwXjh+ ああっ
The built-in functions len and cap take arguments of various types and return a result of type int.
だからなのか
いいのかそんな仕様で
The built-in functions len and cap take arguments of various types and return a result of type int.
だからなのか
いいのかそんな仕様で
455デフォルトの名無しさん
2020/05/01(金) 12:06:06.92ID:Ia4c8IgS Goではintのサイズと配列の最大長は環境依存だからそれで正しい
そして、CopyはWriteを一発呼ぶだけじゃなくて指定された長さをコピーし終えるまで読み書きを繰り返すように実装するもの
だから配列の最大長とか無関係
やってることが全然違うんだから一貫性もクソもない
そして、CopyはWriteを一発呼ぶだけじゃなくて指定された長さをコピーし終えるまで読み書きを繰り返すように実装するもの
だから配列の最大長とか無関係
やってることが全然違うんだから一貫性もクソもない
456デフォルトの名無しさん
2020/05/01(金) 12:20:25.30ID:OD5xAYpx Rob Pike interview: “Go has become the language of cloud infrastructure”
https://evrone.com/rob-pike-interview
https://evrone.com/rob-pike-interview
457デフォルトの名無しさん
2020/05/01(金) 13:10:50.80ID:txiwXjh+ >指定された長さ
ダウト
Copy見てきてください
こいつはReaderからバイトストリーム(厳密には意訳)をEOFに達するまでWriterに書き込み、その書き込みバイト数を返します
サイズなんて指定しません
Writerに書き出すソースが固定のスライスではないだけで、Writerに書き出すという目的から見ればWriteと同じでしょ
まあ違うとあえて言うなら、私とあなたは考え方が違うんでしょうね (私は「何をするか」という目的で言ったので)
ダウト
Copy見てきてください
こいつはReaderからバイトストリーム(厳密には意訳)をEOFに達するまでWriterに書き込み、その書き込みバイト数を返します
サイズなんて指定しません
Writerに書き出すソースが固定のスライスではないだけで、Writerに書き出すという目的から見ればWriteと同じでしょ
まあ違うとあえて言うなら、私とあなたは考え方が違うんでしょうね (私は「何をするか」という目的で言ったので)
458デフォルトの名無しさん
2020/05/01(金) 23:48:52.57ID:txiwXjh+ log.Logger の出力でファイル名も出させるようにして気づいたけど、ソースファイルのパスって実行ファイルの中にしっかりと記録されてる?
Loggerでファイル名を指定すると内部でruntime.Caller呼んでスタック情報拾うんだけど
ログにはソースファイルの完全パスがしっかりと出てくる
実行ファイルを別ディレクトリはにコピーして実行しても出るから、実行ファイルの置き場所を利用している訳じゃない
また、runtimeパッケージがソースファイル情報をもってる訳もないからリンカが埋め込んでるんだろうと推測
runtimeパッケージを使う使わないで、リンカが埋め込む埋め込まないを切り替えるなんて器用な真似はさせていないだろうし
だとすると、ソースファイルの情報って全て記録されているはず(stringsで実行ファイルの中を見た訳じゃないけど)
という推測
完全パスで困るのはユーザ名がしっかり出ちゃうことなんだよな
それが嫌ならユーザディレクトリで開発するなという事なのか
Loggerでファイル名を指定すると内部でruntime.Caller呼んでスタック情報拾うんだけど
ログにはソースファイルの完全パスがしっかりと出てくる
実行ファイルを別ディレクトリはにコピーして実行しても出るから、実行ファイルの置き場所を利用している訳じゃない
また、runtimeパッケージがソースファイル情報をもってる訳もないからリンカが埋め込んでるんだろうと推測
runtimeパッケージを使う使わないで、リンカが埋め込む埋め込まないを切り替えるなんて器用な真似はさせていないだろうし
だとすると、ソースファイルの情報って全て記録されているはず(stringsで実行ファイルの中を見た訳じゃないけど)
という推測
完全パスで困るのはユーザ名がしっかり出ちゃうことなんだよな
それが嫌ならユーザディレクトリで開発するなという事なのか
459デフォルトの名無しさん
2020/05/02(土) 08:59:25.19ID:+Au1iQ6P みんなはGW中は嫁さんとセックスしまくりなの?
独身の俺からすると羨ましいんだけど
独身の俺からすると羨ましいんだけど
460デフォルトの名無しさん
2020/05/02(土) 13:46:40.57ID:iDDOId/p 嫁さんとセクロスなんて1年で飽きるぞ
461デフォルトの名無しさん
2020/05/02(土) 14:11:11.13ID:H63qqmuN セクロスはセフレとしかしないな
462デフォルトの名無しさん
2020/05/02(土) 14:12:11.64ID:1t1QmWMu 疲れるだけだぞ
463デフォルトの名無しさん
2020/05/02(土) 14:21:57.66ID:z5TAOMiI 飽きるか?全然飽きないんだが。
嫁ともっとセクロスしたいわ。
嫁ともっとセクロスしたいわ。
464デフォルトの名無しさん
2020/05/02(土) 14:26:10.42ID:jSLKT64y ∧∧ ミ _ ドスッ
( ,,)┌─┴┴─┐
/ つ. 終 了 │
〜′ /´ └─┬┬─┘
∪ ∪ ││ _ε3
゛゛'゛'゛
( ,,)┌─┴┴─┐
/ つ. 終 了 │
〜′ /´ └─┬┬─┘
∪ ∪ ││ _ε3
゛゛'゛'゛
465デフォルトの名無しさん
2020/05/02(土) 16:06:20.88ID:3+K3/vn9 GoのスレなんだからせめてGopherくんで抜けるかどうかの議論しろよ
466デフォルトの名無しさん
2020/05/02(土) 16:30:21.85ID:1t1QmWMu gopherくんみたいな女いるよな
目がでかくて歯並び悪いやつ
抜ける
目がでかくて歯並び悪いやつ
抜ける
467デフォルトの名無しさん
2020/05/02(土) 17:53:36.77ID:+BhrZUVp 常駐しつつ標準入力からのコマンドを受け付ける構成のプログラム書いてる
だけど、デバッグターミナルからの標準入力はサポートされないんだな(vscode-go/
issues/219)
VScodeの問題かと探したのにdelveの問題?
だけど、デバッグターミナルからの標準入力はサポートされないんだな(vscode-go/
issues/219)
VScodeの問題かと探したのにdelveの問題?
468デフォルトの名無しさん
2020/05/02(土) 17:56:31.80ID:+BhrZUVp ちなみにシグナル使えという話は横に置いといてね
os.Interruptとかのハンドリングはもう入ってる
Windowsでkillしても受け取らないんだこれが
os.Interruptとかのハンドリングはもう入ってる
Windowsでkillしても受け取らないんだこれが
469デフォルトの名無しさん
2020/05/08(金) 09:06:51.86ID:+d3XVyIT470デフォルトの名無しさん
2020/05/08(金) 09:16:00.33ID:le9A8gSm どうでもいい内容なんだよなーそれ
471デフォルトの名無しさん
2020/05/08(金) 09:28:21.26ID:/imhMepR ところどころ抜けてて口頭説明前提の作りで肝心な内容が無い資料公開されてもな
472デフォルトの名無しさん
2020/05/08(金) 09:47:37.47ID:oIDbptWL473デフォルトの名無しさん
2020/05/08(金) 09:48:51.29ID:oIDbptWL474デフォルトの名無しさん
2020/05/08(金) 09:50:21.63ID:oIDbptWL475デフォルトの名無しさん
2020/05/08(金) 16:04:03.09ID:SpWQlQbz 言語仕様より標準ライブラリのクックブック的な本が充実して欲しいかな
結局Goのソースやテストコード読まなきゃ使い方がわからないのが多過ぎるし
結局Goのソースやテストコード読まなきゃ使い方がわからないのが多過ぎるし
476デフォルトの名無しさん
2020/05/08(金) 18:12:47.83ID:QcJ6udj9477デフォルトの名無しさん
2020/05/08(金) 22:59:05.96ID:tAyMPd7a Golang逆引きレシピ(version1.14対応)
って本出してくれ
kindleで5000円までなら買う
って本出してくれ
kindleで5000円までなら買う
478デフォルトの名無しさん
2020/05/09(土) 18:13:17.56ID:m4Vh3zrv 2.0はいつリリースされますのん?
479デフォルトの名無しさん
2020/05/09(土) 18:28:27.39ID:4jg1EkWA 予定は未定
480デフォルトの名無しさん
2020/05/09(土) 19:27:11.31ID:CUL9xwyE 開発陣のモチベーションはどうなんだろう。
なんかrubyと同じような臭いが。
なんかrubyと同じような臭いが。
481デフォルトの名無しさん
2020/05/10(日) 09:38:46.23ID:XQ0sO87J サーバで使われることが割と一般的なコンパイル言語(Java以外)って
Go以外になんかあったっけ
Go以外になんかあったっけ
482デフォルトの名無しさん
2020/05/10(日) 11:01:30.61ID:hDQHcieg apache は何でコンパイルされてる?
483デフォルトの名無しさん
2020/05/10(日) 11:02:41.97ID:ot41mX7+ C#
海外を含めるならWin鯖除外でも今やGoよりは多いんじゃないか
海外を含めるならWin鯖除外でも今やGoよりは多いんじゃないか
484デフォルトの名無しさん
2020/05/10(日) 11:59:28.84ID:XQ0sO87J485デフォルトの名無しさん
2020/05/10(日) 13:04:42.48ID:+Vdduh76 C++
486デフォルトの名無しさん
2020/05/10(日) 14:28:40.79ID:p9tAaMVr Javaじゃね?って言葉を無視するのであれば、Scalaは聞いたことある。
487デフォルトの名無しさん
2020/05/10(日) 15:35:37.07ID:FhPtT+Xo コンパイル言語で伸びそうなのはKotlin
488デフォルトの名無しさん
2020/05/10(日) 18:14:39.27ID:onDYsAIY javaがinnullable化すればいいんだ
いつ達成されるのか
いつ達成されるのか
489デフォルトの名無しさん
2020/05/10(日) 18:21:05.86ID:BbBbqgLD 凄いスレ違い
490デフォルトの名無しさん
2020/05/13(水) 07:56:28.24ID:p0Yu02SZ Goは学習コストが少ないっていう嘘に騙されてるやつとそう信じてる信者が多いのが最大の失敗
コード読むだけじゃ見落とすような罠が簡単につくれるし直感的に分かりづらい仕様と機能不足が多すぎる
書き捨てるだけなら簡単だがチーム開発で採用するには残念すぎる言語
コード読むだけじゃ見落とすような罠が簡単につくれるし直感的に分かりづらい仕様と機能不足が多すぎる
書き捨てるだけなら簡単だがチーム開発で採用するには残念すぎる言語
491デフォルトの名無しさん
2020/05/13(水) 08:32:08.19ID:Q3kP6cCa /\___/\
/ / ヽ ::: \
| (●), 、(●)、 | / ̄ ̄ ̄ ̄ ̄ ̄ ̄
| ,,ノ(、_, )ヽ、,, | < まーたはじまった
| ,;‐=‐ヽ .:::::| \_______
\ `ニニ´ .:::/
/`ー‐--‐‐―´´\
/ / ヽ ::: \
| (●), 、(●)、 | / ̄ ̄ ̄ ̄ ̄ ̄ ̄
| ,,ノ(、_, )ヽ、,, | < まーたはじまった
| ,;‐=‐ヽ .:::::| \_______
\ `ニニ´ .:::/
/`ー‐--‐‐―´´\
492デフォルトの名無しさん
2020/05/13(水) 08:34:54.68ID:+HM7ZWjz 見えない罠が多すぎる言語よりは数段マシなんだよな
493デフォルトの名無しさん
2020/05/14(木) 17:27:46.77ID:ljUxN++I >>447
ものすごく遅い話なんだけど
そっかー、インタフェース定義とファクトリの実装が同じパッケージにある必然性って全くなかったんだな
io.Reader の実装が到るところにあるように、定義と実装を分離させれば済む話だった
あーでもない、こーでもない
いつの間にかそうリファクタリングしていて、アレ?となった
ものすごく遅い話なんだけど
そっかー、インタフェース定義とファクトリの実装が同じパッケージにある必然性って全くなかったんだな
io.Reader の実装が到るところにあるように、定義と実装を分離させれば済む話だった
あーでもない、こーでもない
いつの間にかそうリファクタリングしていて、アレ?となった
494デフォルトの名無しさん
2020/05/15(金) 00:10:35.84ID:WhbhAQET >>490
他と比べたら、って話でしょ
他と比べたら、って話でしょ
495デフォルトの名無しさん
2020/05/15(金) 01:28:18.31ID:kU/eypzI >>493
ていうかinterfaceを返すファクトリというもの自体があまりGo的ではない
その辺は思想がJavaなんかと大きく違うところで、Goでは戻り値には具象型を使うのが基本
interfaceは関数の引数に使うもんで、その関数を使う側のパッケージが必要に応じてinterfaceを実装するんだよ
それに従えば結果的にファクトリとinterface定義は別パッケージになる
ていうかinterfaceを返すファクトリというもの自体があまりGo的ではない
その辺は思想がJavaなんかと大きく違うところで、Goでは戻り値には具象型を使うのが基本
interfaceは関数の引数に使うもんで、その関数を使う側のパッケージが必要に応じてinterfaceを実装するんだよ
それに従えば結果的にファクトリとinterface定義は別パッケージになる
496デフォルトの名無しさん
2020/05/15(金) 05:05:48.78ID:02fpr2+t497デフォルトの名無しさん
2020/05/16(土) 11:46:57.57ID:e+rgeli+ 1.12 の http/request.go に、でっかい落とし穴が
こいつは、1210 行目で ContextType == "multipart/form-data" の処理が未実装
そして、 Chrome は FormData オブジェクトを XMLHttpRequest で send() すると問題のマルチパートで送りつける
よって、FormData は使えない……
他のブラウザだとどうなんだろ?困るな
こいつは、1210 行目で ContextType == "multipart/form-data" の処理が未実装
そして、 Chrome は FormData オブジェクトを XMLHttpRequest で send() すると問題のマルチパートで送りつける
よって、FormData は使えない……
他のブラウザだとどうなんだろ?困るな
498デフォルトの名無しさん
2020/05/16(土) 12:28:15.83ID:bJ5k+aLx xmlHttpRequest.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
じゃダメなん?
じゃダメなん?
499デフォルトの名無しさん
2020/05/16(土) 12:29:08.12ID:e+rgeli+ うーん、コード追ってみたら未実装は間違いでParseMultipartFormを使うらしいけど、わけわかんない
単純にParseFormを置き換えたら、エラーかえしやんの
単純にParseFormを置き換えたら、エラーかえしやんの
500デフォルトの名無しさん
2020/05/16(土) 12:30:20.91ID:e+rgeli+501デフォルトの名無しさん
2020/05/16(土) 12:34:33.17ID:e+rgeli+ 普通、ParseForm が判定して取り込むよね
なんで分離してんの?
なんで分離してんの?
502デフォルトの名無しさん
2020/05/16(土) 13:02:51.76ID:e+rgeli+ エラーが起こる第一原因判明
ヘッダにContent-Typeが無いリクエストでParseMultipartFormすると、パースを打ち切るのではなくてエラーを返す
ショボい作りだ
ヘッダにContent-Typeが無いリクエストでParseMultipartFormすると、パースを打ち切るのではなくてエラーを返す
ショボい作りだ
503デフォルトの名無しさん
2020/05/16(土) 13:05:20.47ID:e+rgeli+ request.go の中身を初めて見たけど、エラー処理は雑だし残念すぎるなコレ
504デフォルトの名無しさん
2020/05/16(土) 13:11:02.15ID:bJ5k+aLx request.MultipartReader() の方を使ってみたら
505デフォルトの名無しさん
2020/05/16(土) 13:14:14.23ID:e+rgeli+506デフォルトの名無しさん
2020/05/16(土) 14:52:00.85ID:9I4cSVvN マルチパートって、要は多段formだっけ
507デフォルトの名無しさん
2020/05/16(土) 14:59:51.10ID:e+rgeli+ なのかな?よく知らない
でも、WebAPIでFormとしてデータを受けるときはParseFormの使用が罠なのは確実
それともbodyを自分で解析するのが定石だったりする?
でも、WebAPIでFormとしてデータを受けるときはParseFormの使用が罠なのは確実
それともbodyを自分で解析するのが定石だったりする?
508デフォルトの名無しさん
2020/05/16(土) 15:12:59.98ID:F08ATzLT >>502
>ヘッダにContent-Typeが無いリクエストでParseMultipartFormすると、パースを打ち切るのではなくてエラーを返す
これは正常な処理だよ
Context-Typeが"multipart/form-data" の場合
Context-Type のmultipart/form-dataの後に続くboundaryをキーにしてmultipartをパースするんだから
ParseMultipartFormがContext-Typeからパースに必要なboundaryを取得できなくてエラーになるのはいたって正常なことだよ
>ヘッダにContent-Typeが無いリクエストでParseMultipartFormすると、パースを打ち切るのではなくてエラーを返す
これは正常な処理だよ
Context-Typeが"multipart/form-data" の場合
Context-Type のmultipart/form-dataの後に続くboundaryをキーにしてmultipartをパースするんだから
ParseMultipartFormがContext-Typeからパースに必要なboundaryを取得できなくてエラーになるのはいたって正常なことだよ
509デフォルトの名無しさん
2020/05/16(土) 15:26:41.59ID:F08ATzLT >>508の補足
Content-Typeが無かったらboundaryが取得できないのにParseMultipartFormでパースしようとするからエラーを返す
Content-Typeが無かったらboundaryが取得できないのにParseMultipartFormでパースしようとするからエラーを返す
510デフォルトの名無しさん
2020/05/16(土) 15:30:06.54ID:9I4cSVvN 「この中にformがいっぱい入ってますよ」っていうformなんだよね
511デフォルトの名無しさん
2020/05/16(土) 15:43:30.65ID:F08ATzLT ヘッダーのContext-Typeで分岐して適切なParseなにがしを呼べってことです。
512デフォルトの名無しさん
2020/05/16(土) 16:52:50.26ID:e+rgeli+ >>511
何のメリットがあって呼ぶ方が判定しなければならないのか、教えてください
何のメリットがあって呼ぶ方が判定しなければならないのか、教えてください
513デフォルトの名無しさん
2020/05/16(土) 17:00:10.79ID:9I4cSVvN 駄々こねてるようにしか見えんぞ
514デフォルトの名無しさん
2020/05/16(土) 17:24:44.07ID:bJ5k+aLx う〜ん、Context-Type が指定されていないのに multipart を自動判別して
くれるライブラリとかフレームワークって他所の言語にあったりするのかな…?
くれるライブラリとかフレームワークって他所の言語にあったりするのかな…?
515デフォルトの名無しさん
2020/05/16(土) 17:34:03.50ID:e+rgeli+ 自動的に判定して分岐できるんだったら、それをライブラリがしないというのは手抜きだろ、と言っている
しかし、例えば文字コードの自動判定ではSJISとUTF-8のどちらでも有効であるマルチバイト文字が存在する
例)"【D"と"縲識"はどちらも E3 80 90 44
このようなケースがある課題では自動処理できないので、ライブラリの外側で何かしらの対応をしてやる必要がある
マルチパートFormという課題でも同じように呼ぶ方が対処してやらなければならない問題があるのだろうと思った
だから、その問題について教えてくださいと書いたんだ
駄々ではないと思うんだが間違っているか?
しかし、例えば文字コードの自動判定ではSJISとUTF-8のどちらでも有効であるマルチバイト文字が存在する
例)"【D"と"縲識"はどちらも E3 80 90 44
このようなケースがある課題では自動処理できないので、ライブラリの外側で何かしらの対応をしてやる必要がある
マルチパートFormという課題でも同じように呼ぶ方が対処してやらなければならない問題があるのだろうと思った
だから、その問題について教えてくださいと書いたんだ
駄々ではないと思うんだが間違っているか?
516デフォルトの名無しさん
2020/05/16(土) 17:40:18.88ID:e+rgeli+ 505で書いたように、一見問題がないような対処はできるけど(自分でも手抜きとはわかってる)、問題点の実体が見えてないと対処に漏れが無いという確証が持てないから
517デフォルトの名無しさん
2020/05/16(土) 17:40:39.14ID:is04b0b3 MIME Type
MIME Encoding
MIME Encoding
518デフォルトの名無しさん
2020/05/16(土) 17:45:07.11ID:GaPEU8I0 それはバウンダリの中身に、
Content-disposition: attachment; filename="xxxxx"
Content-Type: text/plain
なんかが書いてあるからできる動作であって、実はバウンダリの中身はかなり自由。
マルチパートの中にさらにマルチパートを入れるマトリョーシカのようなことをしてもかまわん。仕様上は。
これをきれいに自動でデシリアライズするのは結構難しいと思うけど。
そういう意味では、呼ぶ側が解釈を与えないといかんって割り切りは間違っちゃないんじゃないか?
他のコンパイル言語でどう対応してるのか気になるな。
Content-disposition: attachment; filename="xxxxx"
Content-Type: text/plain
なんかが書いてあるからできる動作であって、実はバウンダリの中身はかなり自由。
マルチパートの中にさらにマルチパートを入れるマトリョーシカのようなことをしてもかまわん。仕様上は。
これをきれいに自動でデシリアライズするのは結構難しいと思うけど。
そういう意味では、呼ぶ側が解釈を与えないといかんって割り切りは間違っちゃないんじゃないか?
他のコンパイル言語でどう対応してるのか気になるな。
519デフォルトの名無しさん
2020/05/16(土) 17:51:34.17ID:9I4cSVvN 仕事でAWSのAPI Gatewayって機能使った時に
マルチパートフォームデータだけは解釈してくれなかった
クラウドサービスの都合上外部のライブラリ入れるにはソースに同梱するしか無く、
それは嫌だったからバックエンドのLambda(goに対応しているけど仕事で使ったのは非go)で
自前でバウンダリのfrom-toを切り取った上でガン無視してリクエストbodyを拾うだけの処理を書いた記憶があるw
完全にスレチだけど
マルチパートフォームデータだけは解釈してくれなかった
クラウドサービスの都合上外部のライブラリ入れるにはソースに同梱するしか無く、
それは嫌だったからバックエンドのLambda(goに対応しているけど仕事で使ったのは非go)で
自前でバウンダリのfrom-toを切り取った上でガン無視してリクエストbodyを拾うだけの処理を書いた記憶があるw
完全にスレチだけど
520デフォルトの名無しさん
2020/05/16(土) 17:54:45.69ID:4LNE0T1O >>515
だってContent-Typeに現れるのはその2種類だけとは限らないから全部ライブラリ任せにはできんだろ。
だってContent-Typeに現れるのはその2種類だけとは限らないから全部ライブラリ任せにはできんだろ。
521デフォルトの名無しさん
2020/05/16(土) 17:55:54.20ID:e+rgeli+ ParseMultipartFormの説明で、必要に応じてParseFormを呼び出しますと書いてるのに、
ヘッダにContent-Typeが無ければエラーとするというParseFormにはない条件を入れてしまっているのがおかしいポイントだと思うんだけど
maxMemory引数はデフォルト値を中に持って、オプションとして変更できるようにするのが、こういったライブラリの定石だから(ソケットのタイムアウト時間設定とか)、これは問題点じゃない
いや引数の設計上の問題点だけど
ヘッダにContent-Typeが無ければエラーとするというParseFormにはない条件を入れてしまっているのがおかしいポイントだと思うんだけど
maxMemory引数はデフォルト値を中に持って、オプションとして変更できるようにするのが、こういったライブラリの定石だから(ソケットのタイムアウト時間設定とか)、これは問題点じゃない
いや引数の設計上の問題点だけど
522デフォルトの名無しさん
2020/05/16(土) 18:06:23.99ID:e+rgeli+ >>520
それが、parsePostForm関数ではその二種類しかハンドリングしてないんだよなぁ
ブラウザ側でとんでもない(サーバで汎用的な方法で解析できない)フォームデータを送るならブラウザの問題だろう
FormDataオブジェクトを使うと発生するContent-Typeくらい自動で処理しないライブラリってどうなの?
それが、parsePostForm関数ではその二種類しかハンドリングしてないんだよなぁ
ブラウザ側でとんでもない(サーバで汎用的な方法で解析できない)フォームデータを送るならブラウザの問題だろう
FormDataオブジェクトを使うと発生するContent-Typeくらい自動で処理しないライブラリってどうなの?
523デフォルトの名無しさん
2020/05/16(土) 18:13:07.38ID:bJ5k+aLx request.parsePostForm() は Content-Type が無ければ application/octet-stream と見なす様だ
func parsePostForm(r *Request) (vs url.Values, err error) {
:
ct := r.Header.Get("Content-Type")
// RFC 7231, section 3.1.1.5 - empty type
// MAY be treated as application/octet-stream
if ct == "" {
ct = "application/octet-stream"
}
ct, _, err = mime.ParseMediaType(ct)
:
func parsePostForm(r *Request) (vs url.Values, err error) {
:
ct := r.Header.Get("Content-Type")
// RFC 7231, section 3.1.1.5 - empty type
// MAY be treated as application/octet-stream
if ct == "" {
ct = "application/octet-stream"
}
ct, _, err = mime.ParseMediaType(ct)
:
524デフォルトの名無しさん
2020/05/16(土) 18:26:33.81ID:bJ5k+aLx RFC 7231 HTTP/1.1: Semantics and Content(日本語訳)
https://triple-underscore.github.io/RFC7231-ja.html#section-3.1.1.5
> 実施においては、リソースの所有者は、[生成元サーバが[所与の表現用
> に正しい Content-Type を供する]ように、常に適正に環境設定されてい
> る]とは限らないため、クライアントには、[ペイロードの内容を精査し
> て、指定された型を上書きする]ものもある【例:MIME sniffing】。その
> ようにするクライアントは、不正な結論を導くリスクを負い、追加のセ
> キュリティリスクを公開し得る(例:"特権拡大")。更には、送信者の意図
> をデータ形式を精査して決定するのは、不可能である: 多くのデータ形
> 式は、処理の意味論においてのみ相違するような、複数の MIME 型に合
> 致する。実装者には、そのような "内容 sniff 法" を利用するときは、
> それを不能化する手段を供することが奨励される。
https://triple-underscore.github.io/RFC7231-ja.html#section-3.1.1.5
> 実施においては、リソースの所有者は、[生成元サーバが[所与の表現用
> に正しい Content-Type を供する]ように、常に適正に環境設定されてい
> る]とは限らないため、クライアントには、[ペイロードの内容を精査し
> て、指定された型を上書きする]ものもある【例:MIME sniffing】。その
> ようにするクライアントは、不正な結論を導くリスクを負い、追加のセ
> キュリティリスクを公開し得る(例:"特権拡大")。更には、送信者の意図
> をデータ形式を精査して決定するのは、不可能である: 多くのデータ形
> 式は、処理の意味論においてのみ相違するような、複数の MIME 型に合
> 致する。実装者には、そのような "内容 sniff 法" を利用するときは、
> それを不能化する手段を供することが奨励される。
525デフォルトの名無しさん
2020/05/16(土) 18:28:03.02ID:e+rgeli+526デフォルトの名無しさん
2020/05/16(土) 18:35:18.02ID:bJ5k+aLx >>525
GitHub リポジトリの develop branch から引っ張ってビルドしたもの
$ go version
go version devel +810c27e9be Wed May 13 11:59:26 2020 +0000
GitHub リポジトリの develop branch から引っ張ってビルドしたもの
$ go version
go version devel +810c27e9be Wed May 13 11:59:26 2020 +0000
527デフォルトの名無しさん
2020/05/16(土) 18:49:32.90ID:e+rgeli+ あ、それ違う
それはParseForm(1180行あたり)から呼ばれる奴だ
つまりマルチパート非対応
ParseMultipartForm(1294行あたり)から呼ばれるmultipartReader(480行あたり)ではContent-Typeが無いと、やっぱりエラーを叩き返してる
それはParseForm(1180行あたり)から呼ばれる奴だ
つまりマルチパート非対応
ParseMultipartForm(1294行あたり)から呼ばれるmultipartReader(480行あたり)ではContent-Typeが無いと、やっぱりエラーを叩き返してる
528デフォルトの名無しさん
2020/05/16(土) 18:53:01.16ID:e+rgeli+ つまり現状でも
マルチパート非対応のParseFormでは、ctが無くてもOK
マルチパート対応のParseMultipartFormでは、ctが無ければエラー
という差異が存在している
マルチパート非対応のParseFormでは、ctが無くてもOK
マルチパート対応のParseMultipartFormでは、ctが無ければエラー
という差異が存在している
529デフォルトの名無しさん
2020/05/16(土) 18:57:51.02ID:e+rgeli+ ParseFormだとURLにフォームくっ付けてContent-Typeがないリクエストを想定してるけど
ParseMultipartFormだと、そういう形式のリクエストは認めていないという違いになって現れる
ParseMultipartFormだと、そういう形式のリクエストは認めていないという違いになって現れる
530デフォルトの名無しさん
2020/05/16(土) 19:07:51.23ID:e+rgeli+ 意図的にContent-Typeのないような感じのフォームデータは許さないサーバを書いてるから、エラーチェックしないという対応だけでも問題なさそう
531デフォルトの名無しさん
2020/05/16(土) 19:47:58.26ID:F08ATzLT >>530
content-typeがない場合
Request.Bodyの内容からapplication/x-www-form-urlencodedやmultipart/form-dataなどのデータ形式(content-type相当)を判断する必要がる。
multipart/form-dataに限ってはboundaryをRequest.Body内容から見つけ出す必要がある。
(keyValueを取得するにもboundaryが必要。)
で、ここで問題なのがRequest.BodyはSTDINからの入力でseekが出来ないのでデータ形式判定後に再度Request.Bodyを読み込むために何らかの方法でRequest.Bodyをキャッシュする必要が出てくる。
(multipart/form-dataはファイルもアップロード出来るのでメモリ上でのキャッシュには向かない)
それとhttp.Serverは常駐プロセスになるので、無駄なリソースを使って自動判別して自動でパースするよりcontent-typeで分岐してパースする方が合理的。
content-typeがない場合
Request.Bodyの内容からapplication/x-www-form-urlencodedやmultipart/form-dataなどのデータ形式(content-type相当)を判断する必要がる。
multipart/form-dataに限ってはboundaryをRequest.Body内容から見つけ出す必要がある。
(keyValueを取得するにもboundaryが必要。)
で、ここで問題なのがRequest.BodyはSTDINからの入力でseekが出来ないのでデータ形式判定後に再度Request.Bodyを読み込むために何らかの方法でRequest.Bodyをキャッシュする必要が出てくる。
(multipart/form-dataはファイルもアップロード出来るのでメモリ上でのキャッシュには向かない)
それとhttp.Serverは常駐プロセスになるので、無駄なリソースを使って自動判別して自動でパースするよりcontent-typeで分岐してパースする方が合理的。
532デフォルトの名無しさん
2020/05/16(土) 21:02:30.65ID:e+rgeli+533デフォルトの名無しさん
2020/05/16(土) 21:30:32.48ID:e+rgeli+ 最終的に
func (i *rInst) ParseForm() error {
v := i.request.Header.Get("Content-Type")
if v == "" {
return i.request.ParseForm()
} else {
return i.request.ParseMultipartForm(100 * 1024)
}
}
とすることにした
func (i *rInst) ParseForm() error {
v := i.request.Header.Get("Content-Type")
if v == "" {
return i.request.ParseForm()
} else {
return i.request.ParseMultipartForm(100 * 1024)
}
}
とすることにした
534デフォルトの名無しさん
2020/05/17(日) 07:48:09.08ID:8deP89zB >>532
> としても、ParseForm内で分岐させない理由にはなってないと思っちゃうんだけど、それについては?
そもそもParseFormがリクエストのパース処理を包括したラッパー関数だと何処で勘違いしたの?
なぜそこまで頑なにRequest-MethodとContent-Typeの値で分岐しようとしないの?
(Content-Typeの値の有無だけ確認して分岐したって言うのは無しよ)
>>533のあなたの最終的な実装を見るとあなたはContent-TypeとParseFormとParseMultipartFormを理解して使って無いの、何となく動くからってやっつけで実装したようにしか見えないの。
> としても、ParseForm内で分岐させない理由にはなってないと思っちゃうんだけど、それについては?
そもそもParseFormがリクエストのパース処理を包括したラッパー関数だと何処で勘違いしたの?
なぜそこまで頑なにRequest-MethodとContent-Typeの値で分岐しようとしないの?
(Content-Typeの値の有無だけ確認して分岐したって言うのは無しよ)
>>533のあなたの最終的な実装を見るとあなたはContent-TypeとParseFormとParseMultipartFormを理解して使って無いの、何となく動くからってやっつけで実装したようにしか見えないの。
535デフォルトの名無しさん
2020/05/17(日) 07:48:39.85ID:8deP89zB >>533
あなたの最終的な実装を元にして実装するならこんな感じかな(勝ってに拡張しちゃってるけど)
func (i *rInst) ParseForm() error {
var err error
r := i.request
ct := r.Header.Get("Content-Type")
ct, _, err = mime.ParseMediaType(ct)
if err == nil {
switch ct {
case "multipart/form-data":
if r.Method == "POST" {
err = r.ParseMultipartForm(100 * 1024)
} else {
err = errors.New(“invalid request”)
}
case “application/json”:
d := json.NewDecoder(r.Body)
// i.Json = make(map[string]interface{})
i.Json = &BindStructure{}
err = d.Decode(&i.Json)
default:
err = r.ParseForm()
}
}
return err
}
まぁ、頑張って。
あなたの最終的な実装を元にして実装するならこんな感じかな(勝ってに拡張しちゃってるけど)
func (i *rInst) ParseForm() error {
var err error
r := i.request
ct := r.Header.Get("Content-Type")
ct, _, err = mime.ParseMediaType(ct)
if err == nil {
switch ct {
case "multipart/form-data":
if r.Method == "POST" {
err = r.ParseMultipartForm(100 * 1024)
} else {
err = errors.New(“invalid request”)
}
case “application/json”:
d := json.NewDecoder(r.Body)
// i.Json = make(map[string]interface{})
i.Json = &BindStructure{}
err = d.Decode(&i.Json)
default:
err = r.ParseForm()
}
}
return err
}
まぁ、頑張って。
536デフォルトの名無しさん
2020/05/17(日) 08:01:02.13ID:Y3GCZn29537デフォルトの名無しさん
2020/05/17(日) 08:02:56.61ID:8deP89zB > i.Json = &BindStructure{}
の部分は
i.Json = BindStructure{}
の間違えでした。
の部分は
i.Json = BindStructure{}
の間違えでした。
538デフォルトの名無しさん
2020/05/17(日) 08:07:59.87ID:Y3GCZn29539デフォルトの名無しさん
2020/05/17(日) 08:10:55.71ID:8deP89zB 寝ぼけてるぽい、もう一回上げ直し
>>533
あなたの最終的な実装を元にして実装するならこんな感じかな(勝ってに拡張しちゃってるけど)
func (i *rInst) ParseForm() error {
var err error
r := i.request
ct := r.Header.Get("Content-Type")
ct, _, err = mime.ParseMediaType(ct)
if err == nil {
switch ct {
case "multipart/form-data":
if r.Method == "POST" {
err = r.ParseMultipartForm(100 * 1024)
} else {
err = errors.New(“invalid request”)
}
case “application/json”:
d := json.NewDecoder(r.Body)
// i.Json = make(map[string]interface{})
// err = d.Decode(&i.Json)
i.Json = &BindStructure{}
err = d.Decode(i.Json)
default:
err = r.ParseForm()
}
}
return err
}
>>533
あなたの最終的な実装を元にして実装するならこんな感じかな(勝ってに拡張しちゃってるけど)
func (i *rInst) ParseForm() error {
var err error
r := i.request
ct := r.Header.Get("Content-Type")
ct, _, err = mime.ParseMediaType(ct)
if err == nil {
switch ct {
case "multipart/form-data":
if r.Method == "POST" {
err = r.ParseMultipartForm(100 * 1024)
} else {
err = errors.New(“invalid request”)
}
case “application/json”:
d := json.NewDecoder(r.Body)
// i.Json = make(map[string]interface{})
// err = d.Decode(&i.Json)
i.Json = &BindStructure{}
err = d.Decode(i.Json)
default:
err = r.ParseForm()
}
}
return err
}
540デフォルトの名無しさん
2020/05/17(日) 08:16:05.54ID:Y3GCZn29 >>535
あ、REST-APIでよく使われる形式なのか
そういうForm使わない呼び出しはサポートしないんで割愛
POST以外のAPIアクセスは事前に拒絶してるから割愛
現状でも問題ないな(手抜き)
あ、REST-APIでよく使われる形式なのか
そういうForm使わない呼び出しはサポートしないんで割愛
POST以外のAPIアクセスは事前に拒絶してるから割愛
現状でも問題ないな(手抜き)
541デフォルトの名無しさん
2020/05/17(日) 08:21:16.95ID:Y3GCZn29542デフォルトの名無しさん
2020/05/17(日) 08:26:21.18ID:8deP89zB スレチになるのでちょっとだけ。
ブラウザが送るって言う解釈とはちょっと違うけどjavascriptで
fetch(url, {
method: 'POST',
headers:{"Content-Type": "application/json"},
body: JSON.stringify(data)
}).then(res => res.json()).then(function(resp) {
// ...
})
みたいにapplication/jsonでリクエストできます。
ブラウザが送るって言う解釈とはちょっと違うけどjavascriptで
fetch(url, {
method: 'POST',
headers:{"Content-Type": "application/json"},
body: JSON.stringify(data)
}).then(res => res.json()).then(function(resp) {
// ...
})
みたいにapplication/jsonでリクエストできます。
543デフォルトの名無しさん
2020/05/17(日) 08:35:11.77ID:Y3GCZn29 >>539
まって、Content-Typeが無いと mime: no media type になる気がするんだが(コード見ただけだけど)
Context-Type が無かったらParseFormの出番だと思う
まって、Content-Typeが無いと mime: no media type になる気がするんだが(コード見ただけだけど)
Context-Type が無かったらParseFormの出番だと思う
544デフォルトの名無しさん
2020/05/17(日) 08:36:58.14ID:8deP89zB >>541
> mime.ParseMultimediaTypeは呼んだ方がいい?
// ct に「;」がある場合に「;」より前を取得してるだけなので
// mime.ParseMultimediaType使わずにこれでもいい
if pos := strings.Index(ct. “;”); pos != -1 {
ct = ct[:pos]
}
> mime.ParseMultimediaTypeは呼んだ方がいい?
// ct に「;」がある場合に「;」より前を取得してるだけなので
// mime.ParseMultimediaType使わずにこれでもいい
if pos := strings.Index(ct. “;”); pos != -1 {
ct = ct[:pos]
}
545デフォルトの名無しさん
2020/05/17(日) 08:38:10.44ID:Y3GCZn29546デフォルトの名無しさん
2020/05/17(日) 08:40:22.86ID:8deP89zB > まって、Content-Typeが無いと mime: no media type になる気がするんだが(コード見ただけだけど)
ごめんこっちに置き換えてw
if pos := strings.Index(ct. “;”); pos != -1 {
ct = ct[:pos]
}
iphoneで書いてるからちょっと適当になりましたw
ごめんこっちに置き換えてw
if pos := strings.Index(ct. “;”); pos != -1 {
ct = ct[:pos]
}
iphoneで書いてるからちょっと適当になりましたw
547デフォルトの名無しさん
2020/05/17(日) 08:45:00.28ID:8deP89zB func (i *rInst) ParseForm() error {
var err error
r := i.request
ct := r.Header.Get("Content-Type")
if pos := strings.Index(ct. “;”); pos != -1 {
ct = ct[:pos]
}
switch ct {
case "multipart/form-data":
if r.Method == "POST" {
err = r.ParseMultipartForm(100 * 1024)
} else {
err = errors.New(“invalid request”)
}
case “application/json”:
d := json.NewDecoder(r.Body)
// i.Json = make(map[string]interface{})
// err = d.Decode(&i.Json)
i.Json = &BindStructure{}
err = d.Decode(i.Json)
default:
err = r.ParseForm()
}
return err
}
var err error
r := i.request
ct := r.Header.Get("Content-Type")
if pos := strings.Index(ct. “;”); pos != -1 {
ct = ct[:pos]
}
switch ct {
case "multipart/form-data":
if r.Method == "POST" {
err = r.ParseMultipartForm(100 * 1024)
} else {
err = errors.New(“invalid request”)
}
case “application/json”:
d := json.NewDecoder(r.Body)
// i.Json = make(map[string]interface{})
// err = d.Decode(&i.Json)
i.Json = &BindStructure{}
err = d.Decode(i.Json)
default:
err = r.ParseForm()
}
return err
}
548デフォルトの名無しさん
2020/05/17(日) 08:51:07.87ID:Y3GCZn29 現時点で
// SetParseMemory は ParseMultipartForm で指定するメモリサイズを変更します。
func (i *rInst) SetParseMemory(size int64) {
i.size = size
}
// ParseForm() error
func (i *rInst) ParseForm() error {
v := i.request.Header.Get("Content-Type")
if v == "" {
return i.request.ParseForm()
} else {
if pos := strings.Index(v, ";"); pos != -1 {
v = v[:pos]
}
if v == "multipart/form-data" {
return i.request.ParseMultipartForm(i.size)
} else {
return i.request.ParseForm()
}
}
}
とした
// SetParseMemory は ParseMultipartForm で指定するメモリサイズを変更します。
func (i *rInst) SetParseMemory(size int64) {
i.size = size
}
// ParseForm() error
func (i *rInst) ParseForm() error {
v := i.request.Header.Get("Content-Type")
if v == "" {
return i.request.ParseForm()
} else {
if pos := strings.Index(v, ";"); pos != -1 {
v = v[:pos]
}
if v == "multipart/form-data" {
return i.request.ParseMultipartForm(i.size)
} else {
return i.request.ParseForm()
}
}
}
とした
549デフォルトの名無しさん
2020/05/17(日) 08:54:49.63ID:Y3GCZn29 あ、これでいいのか
// ParseForm() error
func (i *rInst) ParseForm() error {
v := i.request.Header.Get("Content-Type")
if pos := strings.Index(v, ";"); pos != -1 {
v = v[:pos]
}
if v == "multipart/form-data" {
return i.request.ParseMultipartForm(i.size)
} else {
return i.request.ParseForm()
}
}
// ParseForm() error
func (i *rInst) ParseForm() error {
v := i.request.Header.Get("Content-Type")
if pos := strings.Index(v, ";"); pos != -1 {
v = v[:pos]
}
if v == "multipart/form-data" {
return i.request.ParseMultipartForm(i.size)
} else {
return i.request.ParseForm()
}
}
550デフォルトの名無しさん
2020/05/17(日) 08:55:11.84ID:8deP89zB >>545
>うん、でもそこはAPIの仕様だから
>汎用的なForm解析ならば必要だけど、自分のAPIだと割愛してよいってだけの話
わかりました。
サンプルがちょっとグダグダになってこめんなさいw
とりあえす頑張ってください。
>うん、でもそこはAPIの仕様だから
>汎用的なForm解析ならば必要だけど、自分のAPIだと割愛してよいってだけの話
わかりました。
サンプルがちょっとグダグダになってこめんなさいw
とりあえす頑張ってください。
551デフォルトの名無しさん
2020/05/17(日) 08:57:15.07ID:8deP89zB >>549
それでもいいです。
それでもいいです。
552デフォルトの名無しさん
2020/05/17(日) 09:00:02.16ID:Y3GCZn29 結局、application/json のために ParseForm から ParseMultipartForm を追い出してる?
やっぱり自分的には納得いかない
やっぱり自分的には納得いかない
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【音楽】Perfume・あ~ちゃんの結婚相手「一般男性」は吉田カバンの社長・吉田幸裕氏(41) 高身長で山本耕史似 [Ailuropoda melanoleuca★]
- 日本行き空路49万件キャンセル 中国自粛呼びかけ 日本行きチケット予約の約32%に相当 ★4 [ぐれ★]
- 【サッカー】U-17日本代表、激闘PK戦制す 北朝鮮撃破で6大会ぶり8強入り U17W杯 [久太郎★]
- 【インバウンド】中国人観光客の日本での消費額は年間約2兆円超…中国政府は公務員の出張取り消し [1ゲットロボ★]
- 【サッカー】日本代表、ボリビアに3発快勝 森保監督通算100試合目を飾る…鎌田、町野、中村がゴール [久太郎★]
- XやChatGPTで広範囲の通信障害 投稿や閲覧できず [蚤の市★]
- 毒親「働かないでいつもゴロゴロして!」俺「…」毒親「あっ近隣に熊が出たって!」俺「ふぅ」毒親「どこ行くんだ」
- アンケート調査で「高市発言は問題なし」 93.5%wwwwwwwwwwwwwwwwwwwwwwwww [279254606]
- 生活保護の受給額ってなんでこんなに安いの?
- お前らは“スカイマイルタワー”建設計画を知っているか?
- これ誰か分かるか?
- 支払い詰まってインターネット止まった
