Permalink
Browse files

Merge pull request #16 from sorah/we-need-proxy

We need proxy
  • Loading branch information...
rosylilly committed Oct 31, 2015
2 parents 25af319 + 5b1f77f commit 17ea1f97564f3ebcf0bc72cebdafbfc901ac4b6d
Showing with 203 additions and 2 deletions.
  1. +1 −0 5f/webapp/golang/.gitignore
  2. +13 −0 5f/webapp/golang/Makefile
  3. +185 −0 5f/webapp/golang/proxy.go
  4. +4 −2 5f/webapp/ruby/app.rb
@@ -0,0 +1 @@
+bin
View
@@ -0,0 +1,13 @@
+.PHONY: build run deps
+
+bin/proxy: proxy.go
+ go build -o bin/proxy proxy.go
+
+build: bin/proxy
+
+run: bin/proxy
+ bin/proxy
+
+deps:
+ go get github.com/bradfitz/http2
+ go get github.com/mreiferson/go-httpclient
View
@@ -0,0 +1,185 @@
+package main
+
+import (
+ "crypto/tls"
+ "errors"
+ "fmt"
+ "github.com/bradfitz/http2"
+ httpclient "github.com/mreiferson/go-httpclient"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "sync"
+ "time"
+)
+
+const (
+ BASE_URL = "https://api.five-final.isucon.net:8443/"
+)
+
+var (
+ ENDPOINTS = map[string]string{
+ "/tokens": "https://api.five-final.isucon.net:8443/tokens",
+ "/attacked_list": "https://api.five-final.isucon.net:8443/attacked_list",
+ }
+)
+
+var ValidReqHeaders = map[string]bool{
+ "Accept": true,
+ "Accept-Charset": true,
+ // images (aside from xml/svg), don't generally benefit (generally) from
+ // compression
+ "Accept-Encoding": false,
+ "Accept-Language": true,
+ "Cache-Control": true,
+ "If-None-Match": true,
+ "If-Modified-Since": true,
+ "X-Forwarded-For": true,
+ "X-Perfect-Security-Token": true,
+}
+
+var ValidRespHeaders = map[string]bool{
+ // Do not offer to accept range requests
+ "Accept-Ranges": false,
+ "Cache-Control": true,
+ "Content-Encoding": true,
+ "Content-Type": true,
+ "Transfer-Encoding": true,
+ "Expires": true,
+ "Last-Modified": true,
+ "ETag": true,
+ // override in response with either nothing, or ServerNameVer
+ "Server": false,
+}
+
+var mutex *sync.Mutex
+
+func main() {
+ mutex = new(sync.Mutex)
+ http2.VerboseLogs = true
+
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ fmt.Println("りくえすときた")
+ _, res := getResponse(r)
+
+ if res == nil {
+ fmt.Println("もうなんもかんもだめ")
+ http.Error(w, "だめです", 500)
+ return
+ }
+ defer res.Body.Close()
+
+ bytes, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ fmt.Println("ぼでぃよめなかった")
+ http.Error(w, "だめです", 500)
+ return
+ }
+
+ for k, v := range res.Header {
+ for _, vv := range v {
+ w.Header().Add(k, vv)
+ }
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+
+ fmt.Println("へっだいれた")
+
+ w.WriteHeader(res.StatusCode)
+ fmt.Println("レスポンスこーどおいた")
+
+ fmt.Println("%s", bytes)
+ w.Write(bytes)
+
+ fmt.Println("おわった")
+ })
+
+ http.ListenAndServe(":9293", nil)
+}
+
+func getResponse(req *http.Request) (*http.Request, *http.Response) {
+ endpoint := ENDPOINTS[req.URL.Path]
+
+ nreq, err := http.NewRequest("GET", endpoint, nil)
+ if err != nil {
+ log.Printf("%s", err)
+ return nreq, nil
+ }
+
+ copyHeaders(&nreq.Header, &req.Header)
+ nreq.Header.Set("User-Agent", "isucon-proxy")
+ nreq.Header.Set("Via", "isucon-proxy")
+
+ client := getClinet(req.Header.Get("X-Perfect-Security-Token"))
+ resp, err := client.Do(nreq)
+ if err != nil {
+ log.Printf("Request Error: %s", err)
+ return nreq, nil
+ }
+
+ fmt.Println("りくえすとできた")
+
+ return nreq, resp
+}
+
+func copyHeaders(dst, src *http.Header) {
+ for k, vv := range *src {
+ for _, v := range vv {
+ dst.Add(k, v)
+ }
+ }
+}
+
+var clients = map[string]*http.Client{}
+
+func getClinet(token string) *http.Client {
+ mutex.Lock()
+ defer mutex.Unlock()
+
+ cli, ok := clients[token]
+ if ok {
+ return cli
+ }
+
+ tr := &httpclient.Transport{
+ MaxIdleConnsPerHost: 1,
+ ConnectTimeout: 2 * time.Second,
+ DisableKeepAlives: false,
+ DisableCompression: true,
+ TLSClientConfig: &tls.Config{
+ InsecureSkipVerify: true,
+ },
+ }
+
+ go func() {
+ for {
+ time.Sleep(5 * time.Second)
+ tr.CloseIdleConnections()
+ }
+ }()
+
+ h2tr := &http2.Transport{
+ Fallback: tr,
+ InsecureTLSDial: true,
+ }
+
+ go func() {
+ for {
+ time.Sleep(5 * time.Second)
+ h2tr.CloseIdleConnections()
+ }
+ }()
+
+ client := &http.Client{Transport: tr}
+ client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
+ if len(via) >= 8 {
+ return errors.New("Too many redirects")
+ }
+ return nil
+ }
+
+ clients[token] = client
+
+ return client
+}
View
@@ -204,13 +204,15 @@ def fetch_http(headers, params, call_uri, conf)
end
end
+PROXY_HOST = ENV['MY_PROXY_HOST'] || 'localhost'
+
Isucon5f::Endpoint.new('ken', 'GET', nil, nil, 'http://api.five-final.isucon.net:8080/%s')
Isucon5f::Endpoint.new('ken2', 'GET', nil, nil, 'http://api.five-final.isucon.net:8080/')
Isucon5f::Endpoint.new('surname', 'GET', nil, nil, 'http://api.five-final.isucon.net:8081/surname')
Isucon5f::Endpoint.new('givenname', 'GET', nil, nil, 'http://api.five-final.isucon.net:8081/givenname')
Isucon5f::Endpoint.new('tenki', 'GET', 'param', 'zipcode', 'http://api.five-final.isucon.net:8988/')
-Isucon5f::Endpoint.new('perfectsec', 'GET', 'header', 'X-PERFECT-SECURITY-TOKEN', 'https://api.five-final.isucon.net:8443/tokens')
-Isucon5f::Endpoint.new('perfectsec_attacked', 'GET', 'header', 'X-PERFECT-SECURITY-TOKEN', 'https://api.five-final.isucon.net:8443/attacked_list')
+Isucon5f::Endpoint.new('perfectsec', 'GET', 'header', 'X-PERFECT-SECURITY-TOKEN', "http://#{PROXY_HOST}:9293/tokens")
+Isucon5f::Endpoint.new('perfectsec_attacked', 'GET', 'header', 'X-PERFECT-SECURITY-TOKEN', "http://#{PROXY_HOST}:9293/attacked_list")
class Isucon5f::WebApp < Sinatra::Base
use Rack::Session::Cookie, secret: (ENV['ISUCON5_SESSION_SECRET'] || 'tonymoris')

0 comments on commit 17ea1f9

Please sign in to comment.