Skip to content
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
@@ -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
@@ -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
}
@@ -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.
You can’t perform that action at this time.