Created
April 19, 2019 20:49
-
-
Save jhonata-menezes/69d54048942e8d7bc796b4eb4749474a to your computer and use it in GitHub Desktop.
teste com http.client e libcurl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// teste com biblioteca http.client e go-curl | |
// instalar as seguintes libs | |
// go get github.com/andelf/go-curl && github.com/mmcloughlin/spherand && go get github.com/parnurzeal/gorequest | |
// no momento a lib github.com/andelf/go-curl não é compativel com go 1.12, use a 1,11 | |
// necessário ter a libcurl instalada | |
// o segundo parametro serve para usar com libcurl | |
// go run sinesp.go aaa0010 1 | |
import ( | |
"crypto/hmac" | |
"crypto/sha1" | |
"encoding/hex" | |
"encoding/xml" | |
"fmt" | |
"github.com/andelf/go-curl" | |
"github.com/mmcloughlin/spherand" | |
"github.com/parnurzeal/gorequest" | |
"math/rand" | |
"net" | |
"os" | |
"regexp" | |
"strings" | |
"time" | |
"log" | |
) | |
const URL_API_SINESP = "https://cidadao.sinesp.gov.br/sinesp-cidadao/mobile/consultar-placa/v4" | |
const USER_AGENT = "SinespCidadao / 3.0.2.1 CFNetwork / 758.2.8 Darwin / 15.0.0" | |
const SECRET = "#8.1.0#g8LzUadkEHs7mbRqbX5l" | |
func main() { | |
sinespPlaca := GetPlacaVeicular(os.Args[1]) | |
log.Printf("%#v", sinespPlaca) | |
} | |
type RetornoSinesp struct { | |
CodigoRetorno int `xml:"codigoRetorno"` // 0 | |
MensagemRetorno string `xml:"mensagemRetorno"` // Sem erros. | |
CodigoSituacao int `xml:"codigoSituacao"` // 0 | |
Situacao string `xml:"situacao"` // Sem restrição | |
Modelo string `xml:"modelo"` // FORD/ESCORT 1.8 XR3 | |
Marca string `xml:"marca"` // FORD/ESCORT 1.8 XR3 | |
Cor string `xml:"cor"` // Cinza | |
Ano int `xml:"ano"` // 1990 | |
AnoModelo int `xml:"anoModelo"` // 1990 | |
Placa string `xml:"placa"` // AAA0001 | |
Data string `xml:"data"` // 02/04/2019 às 22:08:06 | |
Uf string `xml:"uf"` // PR | |
Municipio string `xml:"municipio"` // CURITIBA | |
Chassi string `xml:"chassi"` // 49500 | |
DataAtualizacaoCaracteristicasVeiculo string `xml:"dataAtualizacaoCaracteristicasVeiculo"` // 22/02/2019 | |
DataAtualizacaoRouboFurto string `xml:"dataAtualizacaoRouboFurto"` // 01/04/2019 | |
DataAtualizacaoAlarme string `xml:"dataAtualizacaoAlarme"` // 01/04/2019 | |
} | |
type SinespPlacaAPI struct { | |
CodigoRetorno int `xml:"codigoRetorno" json:"codigo_retorno"` | |
MensagemRetorno string `xml:"mensagemRetorno" json:"mensagem_retorno"` | |
CodigoSituacao int `xml:"codigoSituacao" json:"codigo_situacao"` | |
Situacao string `xml:"situacao" json:"situacao"` | |
Modelo string `xml:"modelo" json:"modelo"` | |
Marca string `xml:"marca" json:"marca"` | |
Cor string `xml:"cor" json:"cor"` | |
Ano int `xml:"ano" json:"ano"` | |
AnoModelo int `xml:"anoModelo" json:"ano_modelo"` | |
Placa string `xml:"placa" json:"placa"` | |
Data time.Time `xml:"data" json:"data"` | |
Uf string `xml:"uf" json:"uf"` | |
Municipio string `xml:"municipio" json:"municipio"` | |
Chassi string `xml:"chassi" json:"chassi"` | |
DataAtualizacaoCaracteristicasVeiculo time.Time `xml:"dataAtualizacaoCaracteristicasVeiculo" json:"data_atualizacao_caracteristicas_veiculo"` | |
DataAtualizacaoRouboFurto time.Time `xml:"dataAtualizacaoRouboFurto" json:"data_atualizacao_roubo_furto"` | |
DataAtualizacaoAlarme time.Time `xml:"dataAtualizacaoAlarme" json:"data_atualizacao_alarme"` | |
} | |
func (r *SinespPlacaAPI) Parse(sinesp *RetornoSinesp) { | |
r.CodigoRetorno = sinesp.CodigoRetorno | |
r.MensagemRetorno = sinesp.MensagemRetorno | |
r.CodigoSituacao = sinesp.CodigoSituacao | |
r.Situacao = sinesp.Situacao | |
r.Cor = sinesp.Cor | |
r.Ano = sinesp.Ano | |
r.AnoModelo = sinesp.AnoModelo | |
r.Placa = strings.ToLower(sinesp.Placa) | |
r.Uf = sinesp.Uf | |
r.Municipio = sinesp.Municipio | |
r.Chassi = sinesp.Chassi | |
r.Modelo = sinesp.Modelo | |
r.Marca = sinesp.Marca | |
marca := strings.SplitN(sinesp.Marca, "/", 2) | |
if len(marca) == 2 { | |
r.Marca = marca[0] | |
r.Modelo = marca[1] | |
} | |
if sinesp.Data != "" { | |
t, err := time.Parse("02/01/2006 às 15:04:05", sinesp.Data) | |
if err == nil { | |
r.Data = t | |
} | |
} | |
if sinesp.DataAtualizacaoCaracteristicasVeiculo != "" { | |
t, err := time.Parse("02/01/2006", sinesp.DataAtualizacaoCaracteristicasVeiculo) | |
if err == nil { | |
r.DataAtualizacaoCaracteristicasVeiculo = t | |
} | |
} | |
if sinesp.DataAtualizacaoRouboFurto != "" { | |
t, err := time.Parse("02/01/2006", sinesp.DataAtualizacaoRouboFurto) | |
if err == nil { | |
r.DataAtualizacaoRouboFurto = t | |
} | |
} | |
if sinesp.DataAtualizacaoAlarme != "" { | |
t, err := time.Parse("02/01/2006", sinesp.DataAtualizacaoAlarme) | |
if err == nil { | |
r.DataAtualizacaoAlarme = t | |
} | |
} | |
} | |
func GetPlacaVeicular(placa string) *SinespPlacaAPI { | |
f := CreateFromPlaca(placa) | |
dadosPlaca := new (RetornoSinesp) | |
if len(os.Args) == 3 { | |
dadosPlaca, _ = f.RequestCurl() | |
} else { | |
dadosPlaca, _ = f.Request() | |
} | |
if dadosPlaca == nil { | |
return nil | |
} | |
return ToResponseAPI(dadosPlaca) | |
} | |
type ResponseAPI struct { | |
XMLName xml.Name `xml:"Envelope"` | |
Text string `xml:",chardata"` | |
Soap string `xml:"soap,attr"` | |
Body struct { | |
Text string `xml:",chardata"` | |
GetStatusResponse struct { | |
Text string `xml:",chardata"` | |
Ns2 string `xml:"ns2,attr"` | |
Return RetornoSinesp `xml:"return"` | |
} `xml:"getStatusResponse"` | |
} `xml:"Body"` | |
} | |
type Form struct { | |
Envelope Envelope2 `xml:"v:Envelope"` | |
} | |
type Envelope2 struct{ | |
XMLNS string `xml:"xmlns:v,attr"` | |
Header struct { | |
Aparelho string `xml:"b"` | |
SO string `xml:"c"` | |
Versao string `xml:"d"` | |
Latitude string `xml:"i"` | |
Versao2 string `xml:"e"` | |
IP string `xml:"f"` | |
Token string `xml:"g"` | |
Vazio string `xml:"k"` | |
Longitude string `xml:"h"` | |
Hora string `xml:"l"` | |
Hash string `xml:"m"` | |
} `xml:"v:Header"` | |
Body struct { | |
N0 struct{ | |
XMLNS string `xml:"xmlns:n0,attr"` | |
Placa string `xml:"a"` | |
} `xml:"n0:getStatus"` | |
} `xml:"v:Body"` | |
} | |
func CreateFromPlaca(placa string) *Form { | |
f := new(Form) | |
lat, lng := spherand.Geographical() | |
f.Envelope.XMLNS = "http://schemas.xmlsoap.org/soap/envelope/" | |
f.Envelope.Body.N0.XMLNS = "http://soap.ws.placa.service.sinesp.serpro.gov.br/" | |
f.Envelope.Header.Aparelho = "samsung GT-I9192" | |
f.Envelope.Header.SO = "ANDROID" | |
f.Envelope.Header.Versao = "8.1.0" | |
f.Envelope.Header.Latitude = fmt.Sprintf("%f", lat) | |
f.Envelope.Header.Versao2 = "4.1.5" | |
f.Envelope.Header.IP = RandomIPV4() | |
f.Envelope.Header.Longitude = fmt.Sprintf("%f", lng) | |
f.Envelope.Header.Hora = time.Now().Format("2006-01-02 15:04:05") | |
f.Envelope.Header.Hash = "8797e74f0d6eb7b1ff3dc114d4aa12d3" | |
f.Envelope.Body.N0.Placa = placa | |
f.GenerateToken() | |
return f | |
} | |
func RandomIPV4() string { | |
size := 4 | |
ip := make([]byte, size) | |
for i := 0; i < size; i++ { | |
ip[i] = byte(rand.Intn(256)) | |
} | |
return net.IP(ip).To4().String() | |
} | |
func (f *Form) GenerateToken() { | |
h := hmac.New(sha1.New, []byte(f.Envelope.Body.N0.Placa + SECRET)) | |
h.Write([]byte(f.Envelope.Body.N0.Placa)) | |
f.Envelope.Header.Token = hex.EncodeToString(h.Sum(nil)) | |
} | |
func (f *Form) ToXML() (string) { | |
by, err := xml.Marshal(f) | |
if err != nil { | |
return "" | |
} | |
byStr := string(by)[6:] | |
byStr = byStr[:(len(byStr) - 7)] | |
byStr = fmt.Sprintf("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>%s", byStr) | |
return byStr | |
} | |
func (f *Form) RequestCurl() (*RetornoSinesp, error) { | |
easy := RequestCurl() | |
defer easy.Cleanup() | |
by := []byte{} | |
if easy != nil { | |
easy.Setopt(curl.OPT_URL, URL_API_SINESP) | |
easy.Setopt(curl.OPT_POST, true) | |
easy.Setopt(curl.OPT_POSTFIELDS, f.ToXML()) | |
callback := func (buf []byte, userdata interface{}) bool { | |
by = buf | |
return true | |
} | |
easy.Setopt(curl.OPT_WRITEFUNCTION, callback) | |
err := easy.Perform() | |
if err != nil { | |
return nil, err | |
} | |
} | |
return &ToResponseApi(by).Body.GetStatusResponse.Return, nil | |
} | |
func (f *Form) Request() (*RetornoSinesp, error) { | |
g := Request() | |
//g.SetDebug(true) | |
res, by, errs := g.Post(URL_API_SINESP). | |
Set("Content-type", "application/xml;charset=\"utf-8\""). | |
Set("User-Agent", USER_AGENT). | |
Set("cache-control", "no-cache"). | |
Set("Pragma", "no-cache"). | |
Set("Accept", "*/*"). | |
Timeout(10 * time.Second). | |
Proxy("http://177.185.159.62:8080").Type("xml").SendString(f.ToXML()).EndBytes() | |
if len(errs) > 0 { | |
log.Println(errs, res) | |
return nil, errs[0] | |
} | |
return &ToResponseApi(by).Body.GetStatusResponse.Return, nil | |
} | |
func ToResponseAPI(api *RetornoSinesp) *SinespPlacaAPI { | |
r := new(SinespPlacaAPI) | |
r.Parse(api) | |
return r // alterar proxy, adquirido em 19/04/2019 | |
} | |
func ToResponseApi(res []byte) *ResponseAPI { | |
r := new(ResponseAPI) | |
err := xml.Unmarshal(res, r) | |
if err != nil { | |
log.Println(err) | |
} | |
return r | |
} | |
var validacaoPlacaVeicular, _ = regexp.Compile("^[A-Za-z]{3}[0-9][A-Za-z0-9][0-9]{2}$") | |
func PlacaValidacao(placa string) bool { | |
return validacaoPlacaVeicular.MatchString(placa) | |
} | |
func Request() *gorequest.SuperAgent { | |
g := gorequest.New() | |
// alterar proxy, adquirido em 19/04/2019 | |
return g | |
} | |
func RequestCurl() *curl.CURL { | |
easy := curl.EasyInit() | |
easy.Setopt(curl.OPT_HTTPHEADER, []string{ | |
"Content-type: application/xml;charset=\"utf-8\"", | |
"User-Agent: "+ USER_AGENT, | |
"cache-control: no-cache", | |
"Pragma: no-cache", | |
"Accept: */*", | |
}) | |
easy.Setopt(curl.OPT_PROXY, "http://177.185.159.62:8080") | |
easy.Setopt(curl.OPT_TIMEOUT, 10) | |
return easy | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment