Closed kai-matsudate closed 7 months ago
faradayを選んでみた,faradayで検索してこちらを見つけた. quick guideがあったので読んでみる.
ガイドの通り,ローカルでgem install faraday
を実行してみた.
以下のログが出た.
Successfully installed faraday-2.9.0
Parsing documentation for faraday-2.9.0
Installing ri documentation for faraday-2.9.0
Done installing documentation for faraday after 0 seconds
1 gem installed
A new release of RubyGems is available: 3.4.10 → 3.5.9!
Run `gem update --system 3.5.9` to update your installation.
readmeを読んで,以下のコードを書いた.
require 'faraday'
response = Faraday.get('http://httpbingo.org')
puts response.status
puts response.headers
puts response.body
こんなログが出た.
200
{"access-control-allow-credentials"=>"true", "access-control-allow-origin"=>"*", "content-security-policy"=>"default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' camo.githubusercontent.com", "content-type"=>"text/html; charset=utf-8", "date"=>"Thu, 18 Apr 2024 02:35:00 GMT", "transfer-encoding"=>"chunked", "content-encoding"=>"gzip", "server"=>"Fly/f28a2f4b (2024-04-16)", "via"=>"1.1 fly.io", "fly-request-id"=>"01HVQGXAZ8WA7WPT14WR9K50P9-nrt"}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' value='text/html;charset=utf8'>
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
<title>go-httpbin(1): HTTP Client Testing Service</title>
<style type='text/css' media='all'>
/* style: man */
body#manpage {margin:0;background:#fff;}
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
.mp h2 {margin:10px 0 0 0}
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
.mp h3 {margin:0 0 0 4ex}
.mp dt {margin:0;clear:left}
.mp dt.flush {float:left;width:8ex}
.mp dd {margin:0 0 0 9ex}
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
.mp pre {margin-bottom:20px}
.mp pre+h2,.mp pre+h3 {margin-top:22px}
.mp h2+pre,.mp h3+pre {margin-top:5px}
.mp img {display:block;margin:auto}
.mp h1.man-title {display:none}
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
.mp h2 {font-size:16px;line-height:1.25}
.mp h1 {font-size:20px;line-height:2}
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
.mp u {text-decoration:underline}
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
.mp b.man-ref {font-weight:normal;color:#434241}
.mp pre {padding:0 4ex}
.mp pre code {font-weight:normal;color:#434241}
.mp h2+pre,h3+pre {padding-left:0}
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
ol.man-decor {width:100%}
ol.man-decor li.tl {text-align:left}
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
ol.man-decor li.tr {text-align:right;float:right}
</style>
<style type='text/css' media='all'>
/* style: 80c */
.mp {max-width:86ex}
ul {list-style: None; margin-left: 1em!important}
.man-navigation {left:101ex}
</style>
</head>
<body id='manpage'>
<div class='mp'>
<h1>go-httpbin(1)</h1>
<p>A golang port of the venerable <a href="https://httpbin.org/">httpbin.org</a> HTTP request & response testing service.</p>
<h2 id="ENDPOINTS">ENDPOINTS</h2>
<ul>
<li><a href="/"><code>/</code></a> This page.</li>
<li><a href="/absolute-redirect/6"><code>/absolute-redirect/:n</code></a> 302 Absolute redirects <em>n</em> times.</li>
<li><a href="/anything"><code>/anything/:anything</code></a> Returns anything that is passed to request.</li>
<li><a href="/base64/aHR0cGJpbmdvLm9yZw=="><code>/base64/:value</code></a> Decodes a Base64-encoded string.</li>
<li><a href="/base64/decode/aHR0cGJpbmdvLm9yZw=="><code>/base64/decode/:value</code></a> Explicit URL for decoding a Base64 encoded string.</li>
<li><a href="/base64/encode/httpbingo.org"><code>/base64/encode/:value</code></a> Encodes a string into URL-safe Base64.</li>
<li><a href="/basic-auth/user/passwd"><code>/basic-auth/:user/:passwd</code></a> Challenges HTTPBasic Auth.</li>
<li><a href="/bearer"><code>/bearer</code></a> Checks Bearer token header - returns 401 if not set.</li>
<li><a href="/brotli"><code><del>/brotli</del></code></a> Returns brotli-encoded data.</del> <i>Not implemented!</i></li>
<li><a href="/bytes/1024"><code>/bytes/:n</code></a> Generates <em>n</em> random bytes of binary data, accepts optional <em>seed</em> integer parameter.</li>
<li><a href="/cache"><code>/cache</code></a> Returns 200 unless an If-Modified-Since or If-None-Match header is provided, when it returns a 304.</li>
<li><a href="/cache/60"><code>/cache/:n</code></a> Sets a Cache-Control header for <em>n</em> seconds.</li>
<li><a href="/cookies"><code>/cookies</code></a> Returns cookie data.</li>
<li><a href="/cookies/delete?k1=&k2="><code>/cookies/delete?name</code></a> Deletes one or more simple cookies.</li>
<li><a href="/cookies/set?k1=v1&k2=v2"><code>/cookies/set?name=value</code></a> Sets one or more simple cookies.</li>
<li><a href="/deflate"><code>/deflate</code></a> Returns deflate-encoded data.</li>
<li><a href="/delay/3"><code>/delay/:n</code></a> Delays responding for <em>min(n, 10)</em> seconds.</li>
<li><code>/delete</code> Returns request data. Allows only <code>DELETE</code> requests.</li>
<li><a href="/deny"><code>/deny</code></a> Denied by robots.txt file.</li>
<li><a href="/digest-auth/auth/user/passwd/MD5"><code>/digest-auth/:qop/:user/:passwd/:algorithm</code></a> Challenges HTTP Digest Auth.</li>
<li><a href="/digest-auth/auth/user/passwd/MD5"><code>/digest-auth/:qop/:user/:passwd</code></a> Challenges HTTP Digest Auth.</li>
<li><a href="/drip?code=200&numbytes=5&duration=5"><code>/drip?numbytes=n&duration=s&delay=s&code=code</code></a> Drips data over a duration after an optional initial delay, then (optionally) returns with the given status code.</li>
<li><a href="/dump/request"><code>/dump/request</code></a> Returns the given request in its HTTP/1.x wire approximate representation.</li>
<li><a href="/encoding/utf8"><code>/encoding/utf8</code></a> Returns page containing UTF-8 data.</li>
<li><a href="/etag/etag"><code>/etag/:etag</code></a> Assumes the resource has the given etag and responds to If-None-Match header with a 200 or 304 and If-Match with a 200 or 412 as appropriate.</li>
<li><a href="/forms/post"><code>/forms/post</code></a> HTML form that submits to <em>/post</em></li>
<li><a href="/get"><code>/get</code></a> Returns GET data.</li>
<li><a href="/gzip"><code>/gzip</code></a> Returns gzip-encoded data.</li>
<li><code>/head</code> Returns response headers. Allows only <code>HEAD</code> requests.</li>
<li><a href="/headers"><code>/headers</code></a> Returns request header dict.</li>
<li><a href="/hidden-basic-auth/user/passwd"><code>/hidden-basic-auth/:user/:passwd</code></a> 404'd BasicAuth.</li>
<li><a href="/html"><code>/html</code></a> Renders an HTML Page.</li>
<li><a href="/hostname"><code>/hostname</code></a> Returns the name of the host serving the request.</li>
<li><a href="/image"><code>/image</code></a> Returns page containing an image based on sent Accept header.</li>
<li><a href="/image/jpeg"><code>/image/jpeg</code></a> Returns a JPEG image.</li>
<li><a href="/image/png"><code>/image/png</code></a> Returns a PNG image.</li>
<li><a href="/image/svg"><code>/image/svg</code></a> Returns a SVG image.</li>
<li><a href="/image/webp"><code>/image/webp</code></a> Returns a WEBP image.</li>
<li><a href="/ip"><code>/ip</code></a> Returns Origin IP.</li>
<li><a href="/json"><code>/json</code></a> Returns JSON.</li>
<li><a href="/links/10"><code>/links/:n</code></a> Returns page containing <em>n</em> HTML links.</li>
<li><code>/patch</code> Returns request data. Allows only <code>PATCH</code> requests.</li>
<li><code>/post</code> Returns request data. Allows only <code>POST</code> requests.</li>
<li><code>/put</code> Returns request data. Allows only <code>PUT</code> requests.</li>
<li><a href="/range/1024"><code>/range/1024?duration=s&chunk_size=code</code></a> Streams <em>n</em> bytes, and allows specifying a <em>Range</em> header to select a subset of the data. Accepts a <em>chunk_size</em> and request <em>duration</em> parameter.</li>
<li><a href="/redirect-to?status_code=307&url=http%3A%2F%2Fexample.com%2F"><code>/redirect-to?url=foo&status_code=307</code></a> 307 Redirects to the <em>foo</em> URL.</li>
<li><a href="/redirect-to?url=http%3A%2F%2Fexample.com%2F"><code>/redirect-to?url=foo</code></a> 302 Redirects to the <em>foo</em> URL.</li>
<li><a href="/redirect/6"><code>/redirect/:n</code></a> 302 Redirects <em>n</em> times.</li>
<li><a href="/relative-redirect/6"><code>/relative-redirect/:n</code></a> 302 Relative redirects <em>n</em> times.</li>
<li><a href="/response-headers?Server=httpbin&Content-Type=text%2Fplain%3B+charset%3DUTF-8"><code>/response-headers?key=val</code></a> Returns given response headers.</li>
<li><a href="/robots.txt"><code>/robots.txt</code></a> Returns some robots.txt rules.</li>
<li><a href="/sse?delay=1s&duration=5s&count=10"><code>/sse?delay=1s&duration=5s&count=10</code></a> a stream of server-sent events.</li>
<li><a href="/status/418"><code>/status/:code</code></a> Returns given HTTP Status code.</li>
<li><a href="/stream-bytes/1024"><code>/stream-bytes/:n</code></a> Streams <em>n</em> random bytes of binary data, accepts optional <em>seed</em> and <em>chunk_size</em> integer parameters.</li>
<li><a href="/stream/20"><code>/stream/:n</code></a> Streams <em>min(n, 100)</em> lines.</li>
<li><a href="/unstable"><code>/unstable</code></a> Fails half the time, accepts optional <em>failure_rate</em> float and <em>seed</em> integer parameters.</li>
<li><a href="/user-agent"><code>/user-agent</code></a> Returns user-agent.</li>
<li><a href="/uuid"><code>/uuid</code></a> Generates a <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">UUIDv4</a> value.</li>
<li><a href="/websocket/echo?max_fragment_size=2048&max_message_size=10240"><code>/websocket/echo?max_fragment_size=2048&max_message_size=10240</code></a> A WebSocket echo service.</li>
<li><a href="/xml"><code>/xml</code></a> Returns some XML</li>
</ul>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<p>Testing an HTTP Library can become difficult sometimes. <a href="http://requestb.in">RequestBin</a> is fantastic for testing POST requests, but doesn't let you control the response. This exists to cover all kinds of HTTP scenarios. Additional endpoints are being considered.</p>
<p>All endpoint responses are JSON-encoded.</p>
<h2 id="EXAMPLES">EXAMPLES</h2>
<h3 id="-curl-http-httpbin-org-ip">$ curl https://httpbingo.org/ip</h3>
<pre><code>{"origin":"73.238.9.52, 77.83.142.42"}
</code></pre>
<h3 id="-curl-http-httpbin-org-user-agent">$ curl https://httpbingo.org/user-agent</h3>
<pre><code>{"user-agent":"curl/7.64.1"}</code></pre>
<h3 id="-curl-http-httpbin-org-get">$ curl https://httpbingo.org/get?foo=bar</h3>
<pre><code>{
"args": {
"foo": [
"bar"
]
},
"headers": {
"Accept": [
"*/*"
],
"Host": [
"httpbingo.org"
],
"User-Agent": [
"curl/7.64.1"
]
},
"origin": "73.238.9.52, 77.83.142.42",
"url": "https://httpbingo.org/get?foo=bar"
}
</code></pre>
<h3 id="-curl-http-httpbin-org-dump-request">$ curl https://httpbingo.org/dump/request?foo=bar</h3>
<pre><code>GET /dump/request?foo=bar HTTP/1.1
Host: httpbingo.org
Accept: */*
User-Agent: curl/7.64.1
</code></pre>
<h3 id="-curl-I-http-httpbin-org-status-418">$ curl -I https://httpbingo.org/status/418</h3>
<pre><code>HTTP/1.1 418 I'm a teapot
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
X-More-Info: http://tools.ietf.org/html/rfc2324
Date: Tue, 13 Jul 2021 13:12:37 GMT
Content-Length: 0
</code></pre>
<h2 id="AUTHOR">AUTHOR</h2>
<p>Ported to Go by <a href="https://github.com/mccutchen">Will McCutchen</a>.</p>
<p>From <a href="https://httpbin.org/">the original</a> <a href="https://kennethreitz.org/">Kenneth Reitz</a> project.</p>
<h2 id="SEE-ALSO">SEE ALSO</h2>
<p><a href="https://httpbin.org/">httpbin.org</a> — the original httpbin</p>
</div>
<a href="https://github.com/mccutchen/go-httpbin"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
</body>
</html>
普通.
readmeを読み進めた. 3rd partyのAPIを利用する際は,connectionクラスを利用すると便利と書いてある. quick guide記載の以下のコードを実行してみることにした.
conn = Faraday.new(
url: 'http://httpbingo.org',
params: {param: '1'},
headers: {'Content-Type' => 'application/json'}
)
response = conn.post('/post') do |req|
req.params['limit'] = 100
req.body = {query: 'chunky bacon'}.to_json
end
# => POST http://httpbingo.org/post?param=1&limit=100
実行したら,以下のように標準エラー出力が出た.
connection_init.rb:1:in `<main>': uninitialized constant Faraday (NameError)
conn = Faraday.new(
^^^^^^^
先ほどは自前で require 'faraday'
を追加していたが,今回はうっかり忘れてしまったので,こけている.
上記はサンプルコードにrequire 'faraday'
がないため起きている事象なので,readmeに注意書きがあると初学者にはわかりやすいかもしれないと感じた.
同様のissueを探したが,見つからなかった. https://github.com/lostisland/faraday/issues?page=7&q=is%3Aissue+require
引き続きreadmeを読んでいるが,全部叩くのは面倒なのでツラっと読んでみる.
response = conn.get('get', { boom: 'zap' }, { 'User-Agent' => 'myapp' })
# => GET http://httpbingo.org/get?boom=zap
上記のコードが貼られていたが,これはconn(Faraday::Connectionのインスタンス)
の初期化を前提としている.
しかし,ドキュメント構成は以下の画像のようになっており,
どちらもh3要素なので同じ区分だと分かりずらい.
faradayの強みはmiddlewareらしい. 以下のスクリプトを書いて実行した.
require 'faraday'
conn = Faraday.new(url: 'http://httpbingo.org') do |builder|
# Calls MyAuthStorage.get_auth_token on each request to get the auth token
# and sets it in the Authorization header with Bearer scheme.
builder.request :authorization, 'Bearer', -> { MyAuthStorage.get_auth_token }
# Sets the Content-Type header to application/json on each request.
# Also, if the request body is a Hash, it will automatically be encoded as JSON.
builder.request :json
# Parses JSON response bodies.
# If the response body is not valid JSON, it will raise a Faraday::ParsingError.
builder.response :json
# Raises an error on 4xx and 5xx responses.
builder.response :raise_error
# Logs requests and responses.
# By default, it only logs the request method and URL, and the request/response headers.
builder.response :logger
end
# A simple example implementation for MyAuthStorage
class MyAuthStorage
def self.get_auth_token
rand(36 ** 8).to_s(36)
end
end
begin
response = conn.post('post', { payload: 'this ruby hash will become JSON' })
rescue Faraday::Error => e
# You can handle errors here (4xx/5xx responses, timeouts, etc.)
puts e.response[:status]
puts e.response[:body]
end
# At this point, you can assume the request was successful
puts response.body
# I, [2023-06-30T14:27:11.776511 #35368] INFO -- request: POST http://httpbingo.org/post
# I, [2023-06-30T14:27:11.776646 #35368] INFO -- request: User-Agent: "Faraday v2.7.8"
# Authorization: "Bearer wibzjgyh"
# Content-Type: "application/json"
# I, [2023-06-30T14:27:12.063897 #35368] INFO -- response: Status 200
# I, [2023-06-30T14:27:12.064260 #35368] INFO -- response: access-control-allow-credentials: "true"
# access-control-allow-origin: "*"
# content-type: "application/json; encoding=utf-8"
# date: "Fri, 30 Jun 2023 13:27:12 GMT"
# content-encoding: "gzip"
# transfer-encoding: "chunked"
# server: "Fly/a0b91024 (2023-06-13)"
# via: "1.1 fly.io"
# fly-request-id: "01H467RYRHA0YK4TQSZ7HS8ZFT-lhr"
# cf-team: "19ae1592b8000003bbaedcf400000001"
予定通りのログが出た.
I, [2024-04-18T11:52:56.235720 #23297] INFO -- request: POST http://httpbingo.org/post
I, [2024-04-18T11:52:56.235748 #23297] INFO -- request: User-Agent: "Faraday v2.9.0"
Authorization: "Bearer fdbn3t77"
Content-Type: "application/json"
I, [2024-04-18T11:52:56.667742 #23297] INFO -- response: Status 200
I, [2024-04-18T11:52:56.667942 #23297] INFO -- response: access-control-allow-credentials: "true"
access-control-allow-origin: "*"
content-type: "application/json; charset=utf-8"
date: "Thu, 18 Apr 2024 02:52:56 GMT"
content-encoding: "gzip"
transfer-encoding: "chunked"
server: "Fly/f28a2f4b (2024-04-16)"
via: "1.1 fly.io"
fly-request-id: "01HVQHY64GD8CG74B6GSGREMAV-nrt"
{"args"=>{}, "headers"=>{"Accept"=>["*/*"], "Accept-Encoding"=>["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"], "Authorization"=>["Bearer fdbn3t77"], "Content-Length"=>["45"], "Content-Type"=>["application/json"], "Host"=>["httpbingo.org"], "User-Agent"=>["Faraday v2.9.0"], "Via"=>["1.1 fly.io"], "X-Forwarded-For"=>["240d:1b:9a:c908:e9e8:5f13:d15c:e662, 2a09:8280:1:7fcb:9efa:a365:aa2a:d036"], "X-Forwarded-Port"=>["80"], "X-Forwarded-Proto"=>["http"], "X-Forwarded-Ssl"=>["off"], "X-Request-Start"=>["t=1713408776336849"]}, "method"=>"POST", "origin"=>"240d:1b:9a:c908:e9e8:5f13:d15c:e662", "url"=>"http://httpbingo.org/post", "data"=>"{\"payload\":\"this ruby hash will become JSON\"}", "files"=>{}, "form"=>{}, "json"=>{"payload"=>"this ruby hash will become JSON"}}
faraday自身はHTTPリクエストを送信しておらず,adapterに任せているらしい.
デフォルトはNet::HTTP
であり,自由に変更ができるとのこと.
以下の例が記載されていた.
conn = Faraday.new(url: 'http://httpbingo.org') do |builder|
builder.adapter :async_http
end
入れれた
$ gem install async-http
Fetching async-http-0.64.1.gem
Successfully installed async-http-0.64.1
Parsing documentation for async-http-0.64.1
Installing ri documentation for async-http-0.64.1
Done installing documentation for async-http after 0 seconds
1 gem installed
以下のスクリプトを実行して,こけた
require 'faraday'
require 'async_http'
conn = Faraday.new(url: 'http://httpbingo.org') do |builder|
builder.adapter :async_http
end
puts conn.get
---
<internal:/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- async_http (LoadError)
from <internal:/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from change_adapter_init.rb:2:in `<main>'
async-httpの呼び方がわかっていなかった. https://github.com/socketry/async-http こっちに書いてた.
readme通りやったが,こけた
require 'faraday'
require 'json'
require 'async'
require 'async/http/internet'
conn = Faraday.new(url: 'http://httpbingo.org') do |builder|
builder.adapter :async_http
end
puts conn.get
---
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/io-event-1.5.1/lib/io/event/support.rb:27: warning: IO::Buffer is experimental and both the Ruby and C interface may change in the future!
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/faraday-2.9.0/lib/faraday/middleware_registry.rb:57:in `lookup_middleware': :async_http is not registered on Faraday::Adapter (Faraday::Error)
from /Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/faraday-2.9.0/lib/faraday/rack_builder.rb:112:in `adapter'
from /Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/forwardable.rb:240:in `adapter'
from change_adapter_init.rb:7:in `block in <main>'
from /Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/faraday-2.9.0/lib/faraday/connection.rb:91:in `initialize'
from /Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/faraday-2.9.0/lib/faraday.rb:98:in `new'
from /Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/faraday-2.9.0/lib/faraday.rb:98:in `new'
from change_adapter_init.rb:6:in `<main>'
あーなるほど
こけた
require 'faraday'
require 'faraday/httpclient'
Faraday.default_adapter = :httpclient
conn = Faraday.new(url: 'http://httpbingo.org') do |builder|
builder.adapter :httpclient
end
puts conn.get
入れていないからそれはそう gemを入れた
gem install httpclient
Fetching httpclient-2.8.3.gem
Successfully installed httpclient-2.8.3
Parsing documentation for httpclient-2.8.3
Installing ri documentation for httpclient-2.8.3
Done installing documentation for httpclient after 0 seconds
1 gem installed
いや,こけるんかい
require 'httpclient'
require 'faraday'
require 'faraday/httpclient'
Faraday.default_adapter = :httpclient
conn = Faraday.new(url: 'http://httpbingo.org') do |builder|
builder.adapter :httpclient
end
puts conn.get
---
<internal:/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- faraday/httpclient (LoadError)
from <internal:/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from change_adapter_init.rb:3:in `<main>'
まあそんなわけないか
$ gem install faraday/httpclient
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError)
bad response Not Found 404 (Gem::RemoteFetcher::FetchError)
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/remote_fetcher.rb:232:in `fetch_http'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/remote_fetcher.rb:248:in `fetch_path'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/resolver/api_set.rb:105:in `versions'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/resolver/api_set.rb:56:in `find_all'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/resolver/composed_set.rb:54:in `block in find_all'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/resolver/composed_set.rb:53:in `map'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/resolver/composed_set.rb:53:in `find_all'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/resolver/best_set.rb:30:in `find_all'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/resolver/installer_set.rb:170:in `find_all'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/resolver/installer_set.rb:61:in `add_always_install'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/dependency_installer.rb:322:in `resolve_dependencies'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/commands/install_command.rb:205:in `install_gem'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/commands/install_command.rb:230:in `block in install_gems'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/commands/install_command.rb:223:in `each'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/commands/install_command.rb:223:in `install_gems'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/commands/install_command.rb:169:in `execute'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/command.rb:327:in `invoke_with_build_args'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/command_manager.rb:252:in `invoke_command'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/command_manager.rb:192:in `process_args'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/command_manager.rb:150:in `run'
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/3.2.0/rubygems/gem_runner.rb:51:in `run'
/Users/matsudatekai/.rbenv/versions/3.2.2/bin/gem:10:in `<main>'
あーこれか
$ gem install faraday-httpclient
Fetching faraday-httpclient-2.0.1.gem
Successfully installed faraday-httpclient-2.0.1
Parsing documentation for faraday-httpclient-2.0.1
Installing ri documentation for faraday-httpclient-2.0.1
Done installing documentation for faraday-httpclient after 0 seconds
1 gem installed
普通に書いてた,くそ
いけた
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' value='text/html;charset=utf8'>
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
<title>go-httpbin(1): HTTP Client Testing Service</title>
<style type='text/css' media='all'>
/* style: man */
body#manpage {margin:0;background:#fff;}
.mp {max-width:100ex;padding:0 9ex 1ex 4ex}
.mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
.mp h2 {margin:10px 0 0 0}
.mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
.mp h3 {margin:0 0 0 4ex}
.mp dt {margin:0;clear:left}
.mp dt.flush {float:left;width:8ex}
.mp dd {margin:0 0 0 9ex}
.mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
.mp pre {margin-bottom:20px}
.mp pre+h2,.mp pre+h3 {margin-top:22px}
.mp h2+pre,.mp h3+pre {margin-top:5px}
.mp img {display:block;margin:auto}
.mp h1.man-title {display:none}
.mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
.mp h2 {font-size:16px;line-height:1.25}
.mp h1 {font-size:20px;line-height:2}
.mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
.mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
.mp u {text-decoration:underline}
.mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
.mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
.mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
.mp b.man-ref {font-weight:normal;color:#434241}
.mp pre {padding:0 4ex}
.mp pre code {font-weight:normal;color:#434241}
.mp h2+pre,h3+pre {padding-left:0}
ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
ol.man-decor {width:100%}
ol.man-decor li.tl {text-align:left}
ol.man-decor li.tc {text-align:center;letter-spacing:4px}
ol.man-decor li.tr {text-align:right;float:right}
</style>
<style type='text/css' media='all'>
/* style: 80c */
.mp {max-width:86ex}
ul {list-style: None; margin-left: 1em!important}
.man-navigation {left:101ex}
</style>
</head>
<body id='manpage'>
<div class='mp'>
<h1>go-httpbin(1)</h1>
<p>A golang port of the venerable <a href="https://httpbin.org/">httpbin.org</a> HTTP request & response testing service.</p>
<h2 id="ENDPOINTS">ENDPOINTS</h2>
<ul>
<li><a href="/"><code>/</code></a> This page.</li>
<li><a href="/absolute-redirect/6"><code>/absolute-redirect/:n</code></a> 302 Absolute redirects <em>n</em> times.</li>
<li><a href="/anything"><code>/anything/:anything</code></a> Returns anything that is passed to request.</li>
<li><a href="/base64/aHR0cGJpbmdvLm9yZw=="><code>/base64/:value</code></a> Decodes a Base64-encoded string.</li>
<li><a href="/base64/decode/aHR0cGJpbmdvLm9yZw=="><code>/base64/decode/:value</code></a> Explicit URL for decoding a Base64 encoded string.</li>
<li><a href="/base64/encode/httpbingo.org"><code>/base64/encode/:value</code></a> Encodes a string into URL-safe Base64.</li>
<li><a href="/basic-auth/user/passwd"><code>/basic-auth/:user/:passwd</code></a> Challenges HTTPBasic Auth.</li>
<li><a href="/bearer"><code>/bearer</code></a> Checks Bearer token header - returns 401 if not set.</li>
<li><a href="/brotli"><code><del>/brotli</del></code></a> Returns brotli-encoded data.</del> <i>Not implemented!</i></li>
<li><a href="/bytes/1024"><code>/bytes/:n</code></a> Generates <em>n</em> random bytes of binary data, accepts optional <em>seed</em> integer parameter.</li>
<li><a href="/cache"><code>/cache</code></a> Returns 200 unless an If-Modified-Since or If-None-Match header is provided, when it returns a 304.</li>
<li><a href="/cache/60"><code>/cache/:n</code></a> Sets a Cache-Control header for <em>n</em> seconds.</li>
<li><a href="/cookies"><code>/cookies</code></a> Returns cookie data.</li>
<li><a href="/cookies/delete?k1=&k2="><code>/cookies/delete?name</code></a> Deletes one or more simple cookies.</li>
<li><a href="/cookies/set?k1=v1&k2=v2"><code>/cookies/set?name=value</code></a> Sets one or more simple cookies.</li>
<li><a href="/deflate"><code>/deflate</code></a> Returns deflate-encoded data.</li>
<li><a href="/delay/3"><code>/delay/:n</code></a> Delays responding for <em>min(n, 10)</em> seconds.</li>
<li><code>/delete</code> Returns request data. Allows only <code>DELETE</code> requests.</li>
<li><a href="/deny"><code>/deny</code></a> Denied by robots.txt file.</li>
<li><a href="/digest-auth/auth/user/passwd/MD5"><code>/digest-auth/:qop/:user/:passwd/:algorithm</code></a> Challenges HTTP Digest Auth.</li>
<li><a href="/digest-auth/auth/user/passwd/MD5"><code>/digest-auth/:qop/:user/:passwd</code></a> Challenges HTTP Digest Auth.</li>
<li><a href="/drip?code=200&numbytes=5&duration=5"><code>/drip?numbytes=n&duration=s&delay=s&code=code</code></a> Drips data over a duration after an optional initial delay, then (optionally) returns with the given status code.</li>
<li><a href="/dump/request"><code>/dump/request</code></a> Returns the given request in its HTTP/1.x wire approximate representation.</li>
<li><a href="/encoding/utf8"><code>/encoding/utf8</code></a> Returns page containing UTF-8 data.</li>
<li><a href="/etag/etag"><code>/etag/:etag</code></a> Assumes the resource has the given etag and responds to If-None-Match header with a 200 or 304 and If-Match with a 200 or 412 as appropriate.</li>
<li><a href="/forms/post"><code>/forms/post</code></a> HTML form that submits to <em>/post</em></li>
<li><a href="/get"><code>/get</code></a> Returns GET data.</li>
<li><a href="/gzip"><code>/gzip</code></a> Returns gzip-encoded data.</li>
<li><code>/head</code> Returns response headers. Allows only <code>HEAD</code> requests.</li>
<li><a href="/headers"><code>/headers</code></a> Returns request header dict.</li>
<li><a href="/hidden-basic-auth/user/passwd"><code>/hidden-basic-auth/:user/:passwd</code></a> 404'd BasicAuth.</li>
<li><a href="/html"><code>/html</code></a> Renders an HTML Page.</li>
<li><a href="/hostname"><code>/hostname</code></a> Returns the name of the host serving the request.</li>
<li><a href="/image"><code>/image</code></a> Returns page containing an image based on sent Accept header.</li>
<li><a href="/image/jpeg"><code>/image/jpeg</code></a> Returns a JPEG image.</li>
<li><a href="/image/png"><code>/image/png</code></a> Returns a PNG image.</li>
<li><a href="/image/svg"><code>/image/svg</code></a> Returns a SVG image.</li>
<li><a href="/image/webp"><code>/image/webp</code></a> Returns a WEBP image.</li>
<li><a href="/ip"><code>/ip</code></a> Returns Origin IP.</li>
<li><a href="/json"><code>/json</code></a> Returns JSON.</li>
<li><a href="/links/10"><code>/links/:n</code></a> Returns page containing <em>n</em> HTML links.</li>
<li><code>/patch</code> Returns request data. Allows only <code>PATCH</code> requests.</li>
<li><code>/post</code> Returns request data. Allows only <code>POST</code> requests.</li>
<li><code>/put</code> Returns request data. Allows only <code>PUT</code> requests.</li>
<li><a href="/range/1024"><code>/range/1024?duration=s&chunk_size=code</code></a> Streams <em>n</em> bytes, and allows specifying a <em>Range</em> header to select a subset of the data. Accepts a <em>chunk_size</em> and request <em>duration</em> parameter.</li>
<li><a href="/redirect-to?status_code=307&url=http%3A%2F%2Fexample.com%2F"><code>/redirect-to?url=foo&status_code=307</code></a> 307 Redirects to the <em>foo</em> URL.</li>
<li><a href="/redirect-to?url=http%3A%2F%2Fexample.com%2F"><code>/redirect-to?url=foo</code></a> 302 Redirects to the <em>foo</em> URL.</li>
<li><a href="/redirect/6"><code>/redirect/:n</code></a> 302 Redirects <em>n</em> times.</li>
<li><a href="/relative-redirect/6"><code>/relative-redirect/:n</code></a> 302 Relative redirects <em>n</em> times.</li>
<li><a href="/response-headers?Server=httpbin&Content-Type=text%2Fplain%3B+charset%3DUTF-8"><code>/response-headers?key=val</code></a> Returns given response headers.</li>
<li><a href="/robots.txt"><code>/robots.txt</code></a> Returns some robots.txt rules.</li>
<li><a href="/sse?delay=1s&duration=5s&count=10"><code>/sse?delay=1s&duration=5s&count=10</code></a> a stream of server-sent events.</li>
<li><a href="/status/418"><code>/status/:code</code></a> Returns given HTTP Status code.</li>
<li><a href="/stream-bytes/1024"><code>/stream-bytes/:n</code></a> Streams <em>n</em> random bytes of binary data, accepts optional <em>seed</em> and <em>chunk_size</em> integer parameters.</li>
<li><a href="/stream/20"><code>/stream/:n</code></a> Streams <em>min(n, 100)</em> lines.</li>
<li><a href="/unstable"><code>/unstable</code></a> Fails half the time, accepts optional <em>failure_rate</em> float and <em>seed</em> integer parameters.</li>
<li><a href="/user-agent"><code>/user-agent</code></a> Returns user-agent.</li>
<li><a href="/uuid"><code>/uuid</code></a> Generates a <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier">UUIDv4</a> value.</li>
<li><a href="/websocket/echo?max_fragment_size=2048&max_message_size=10240"><code>/websocket/echo?max_fragment_size=2048&max_message_size=10240</code></a> A WebSocket echo service.</li>
<li><a href="/xml"><code>/xml</code></a> Returns some XML</li>
</ul>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<p>Testing an HTTP Library can become difficult sometimes. <a href="http://requestb.in">RequestBin</a> is fantastic for testing POST requests, but doesn't let you control the response. This exists to cover all kinds of HTTP scenarios. Additional endpoints are being considered.</p>
<p>All endpoint responses are JSON-encoded.</p>
<h2 id="EXAMPLES">EXAMPLES</h2>
<h3 id="-curl-http-httpbin-org-ip">$ curl https://httpbingo.org/ip</h3>
<pre><code>{"origin":"73.238.9.52, 77.83.142.42"}
</code></pre>
<h3 id="-curl-http-httpbin-org-user-agent">$ curl https://httpbingo.org/user-agent</h3>
<pre><code>{"user-agent":"curl/7.64.1"}</code></pre>
<h3 id="-curl-http-httpbin-org-get">$ curl https://httpbingo.org/get?foo=bar</h3>
<pre><code>{
"args": {
"foo": [
"bar"
]
},
"headers": {
"Accept": [
"*/*"
],
"Host": [
"httpbingo.org"
],
"User-Agent": [
"curl/7.64.1"
]
},
"origin": "73.238.9.52, 77.83.142.42",
"url": "https://httpbingo.org/get?foo=bar"
}
</code></pre>
<h3 id="-curl-http-httpbin-org-dump-request">$ curl https://httpbingo.org/dump/request?foo=bar</h3>
<pre><code>GET /dump/request?foo=bar HTTP/1.1
Host: httpbingo.org
Accept: */*
User-Agent: curl/7.64.1
</code></pre>
<h3 id="-curl-I-http-httpbin-org-status-418">$ curl -I https://httpbingo.org/status/418</h3>
<pre><code>HTTP/1.1 418 I'm a teapot
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
X-More-Info: http://tools.ietf.org/html/rfc2324
Date: Tue, 13 Jul 2021 13:12:37 GMT
Content-Length: 0
</code></pre>
<h2 id="AUTHOR">AUTHOR</h2>
<p>Ported to Go by <a href="https://github.com/mccutchen">Will McCutchen</a>.</p>
<p>From <a href="https://httpbin.org/">the original</a> <a href="https://kennethreitz.org/">Kenneth Reitz</a> project.</p>
<h2 id="SEE-ALSO">SEE ALSO</h2>
<p><a href="https://httpbin.org/">httpbin.org</a> — the original httpbin</p>
</div>
<a href="https://github.com/mccutchen/go-httpbin"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
</body>
</html>
build your ownと書いてあるので,書いてみるか?
アドバイスにしたがって git clone
して,CIを実行した.
# Run unit tests and check code coverage
$ bundle exec rspec
# Check code style
$ bundle exec rubocop
どっちも通った
ruby async_parallel.rb
/Users/matsudatekai/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/io-event-1.5.1/lib/io/event/support.rb:27: warning: IO::Buffer is experimental and both the Ruby and C interface may change in the future!
Time taken: 3.448315
ドキュメントからスクリプトをこぴぺして実行したが,上記のwarningが出た
asyncの開発者の別のリポジトリのissueが解決されていたので読んでみる https://github.com/socketry/io-event/issues/82
よくみたら同じGemを内部で使っていて同じ事象が起きていた.
何したらいいかわからなくなってきた
業務で使ったautocomplete.jsというvanilla jsのライブラリに一旦変えてみる. https://github.com/TarekRaafat/autoComplete.js Apache-2.0 licenseであることを確認.
リポジトリのreadmeを参照.
以下のwarningを確認.
npm i @tarekraafat/autocomplete.js
npm WARN deprecated rollup-plugin-terser@7.0.2: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
npm WARN deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
npm WARN deprecated acorn-dynamic-import@3.0.0: This is probably built in to whatever tool you're using. If you still need it... idk
added 229 packages, and audited 230 packages in 3s
12 packages are looking for funding
run `npm fund` for details
2 vulnerabilities (1 moderate, 1 critical)
To address all issues, run:
npm audit fix
Run `npm audit` for details.
しょうがないので,業務上ででくわした以下のバグを報告する.
autocompleteの候補が変な場所に出てくる.
上記の再現手順を確認して,可能であればPRとしてあげる. 時間内で厳しければIssueとしてあげることにした.
別環境で再現できなさそうで辛い.
いうて再現状況が結構限定的な気もするので,報告する必要性もない気がしてきた.
別にバグではなかった.非常に残念.
faradayのやつだけ報告して終わるか.
もうちょっとマシなFBできないか探索だけしてみる.
画像が死んでいたので報告する. https://www.rubydoc.info/github/lostisland/faraday
画像のパスは合っている気がするので,ローカルで自動生成したRdocでは表示されているが,https://www.rubydoc.info/github/lostisland/faraday のドメインでは参照できない,というだけな気がする.
faraday側でテンプレがあったので,下に書いていく.
When you access to this page, could not see home-logo image, like following.
Seems to be it is local relative path, so you have to change image path like below.
https://github.com/lostisland/faraday/raw/main/docs/_media/home-logo.svg
Just Access to following page. https://www.rubydoc.info/github/lostisland/faraday
上記でいいか確認して,Issueを出そう!
This is a work log of a "OSS Gate workshop". "OSS Gate workshop" is an activity to increase OSS developers. Here's been discussed in Japanese. Thanks.
作業ログ作成時の説明
以下のテンプレートを埋めてタイトルに設定します。埋め方例はスクロールすると見えてきます。
タイトル例↓:
OSS Gateワークショップ関連情報