# 说明

使用了国内使用率较高的 HTTP 库做的封装,用于 HTTP 请求

# 使用案例

/*JavaScript*/
let okhttp = require('ok-http')
let http = okhttp.create({         // 创建客户端
    connectTimeout: 5000,	       // 连接服务器超时时间, 5秒
    readTimeout: 5000,             // 读取超时时间
    baseUrl: '',                   // url前缀
    headers: {
        'Content-Type': 'application/json',
        'X-Application': 'yoyo'
    }
})

// 发起 get 请求
let res = http.get({
        url: 'http://www.baidu.com'
})

// 发起 post 请求
let res = http.post({
        url: 'http://www.baidu.com',
        data: {                    // body
            username: '123',
            password: 'qwejhkahjksdhkjas'
        }
})

/* 
    res 有四个属性 
    res.code / res.statusCode   http 状态码
    res.data                    如果 body 可以解析成 object 时, 他是 object, 解析失败就是 undefined
    res.text                    响应纯文本
    res.base64                  响应数据的 base64 格式的文本
*/
 

# 源码

/*JavaScript*/
let OkHttpClient = require('com.squareup.okhttp.OkHttpClient')
let TimeUnit = require('java.util.concurrent.TimeUnit')
let Request = require('com.squareup.okhttp.Request')
let Builder = require('com.squareup.okhttp.Request$Builder')
let RequestBody = require('com.squareup.okhttp.RequestBody')
let Base64 = require('java.util.Base64')

function create(config) {
    let httpClient = {}
    httpClient.__okHttpClient__ = new OkHttpClient();

    httpClient.send = function (config) {
        let builder = new Builder();
		if (this.headers !== undefined) {
			for (let i = 0; i < this.headers.length; i++) {
				builder.addHeader(this.headers[i].key, this.headers[i].value)
			}
		}
        if (typeof config === 'object') {
            builder.url(typeof config.url === 'string' ? (this.baseUrl ? this.baseUrl + config.url : config.url) : config.url)
            let dataText = '';
            if (typeof config.data === 'string') {
                dataText = config.data
            } else if (typeof config.data === 'object') {
                dataText = JSON.stringify(config.data)
            }

            if (typeof config.method === 'string') {
                let method = config.method.toUpperCase()
                if (method === 'GET') {
                    builder.get()
                } else if (method === 'POST') {
                    builder.post(RequestBody.create(null, dataText))
                } else if (method === 'DELETE') {
                    builder.delete()
                } else if (method === 'PUT') {
                    builder.put(RequestBody.create(null, dataText))
                }
            }
        }

        let request = builder.build()
        let nativeResponse = this.__okHttpClient__.newCall(request).execute();
        let response = {}
        response.bytes = nativeResponse.body().bytes()
        // response.__body__ = rawResponse.body()
        // response.text = rawResponse.body().string()
        response.text = new java.lang.String(response.bytes, 'utf-8')
        try {
            response.data = JSON.parse(response.text)
        } catch (e) {
            response.data = undefined
        }
        Object.defineProperty(response, 'base64', {
            get: function() {
                return Base64.getEncoder().encodeToString(this.bytes)
            }
        });

        response.__headers__ = nativeResponse.headers()
        Object.defineProperty(response, 'headers', {
            get: function() {
                if (this.__headersCopy__ === undefined) {
                    let headers = {}
                    var nativeHeaders = nativeResponse.headers();
                    var nativeHeaderArray = nativeHeaders.names().toArray();
                    for (let i = 0; i < nativeHeaderArray.length; i++) {
                        let nativeValues = nativeHeaders.values(nativeHeaderArray[i])
                        if (nativeValues.size() === 1) {
                            headers[nativeHeaderArray[i]] = nativeValues.get(0)
                        } else {
                            headers[nativeHeaderArray[i]] = []
                            for (let j = 0; j < nativeValues.size(); j++) {
                                headers[nativeHeaderArray[i]].push(nativeValues.get(j))
                            }
                        }
                    }
                    this.__headersCopy__ = headers
                }
                return this.__headersCopy__
            }
        });
        /*response.headers = {}
        print(java.lang.System.currentTimeMillis())
        var nativeHeaders = nativeResponse.headers();
        var nativeHeaderArray = nativeHeaders.names().toArray();
        for (let i = 0; i < nativeHeaderArray.length; i++) {
            let nativeValues = nativeHeaders.values(nativeHeaderArray[i])
            if (nativeValues.size() === 1) {
                response.headers[nativeHeaderArray[i]] = nativeValues.get(0)
            } else {
                response.headers[nativeHeaderArray[i]] = []
                for (let j = 0; j < nativeValues.size(); j++) {
                    response.headers[nativeHeaderArray[i]].push(nativeValues.get(j))
                }
            }
        }
        print(java.lang.System.currentTimeMillis())*/

        response.code = nativeResponse.code()
        response.statusCode = response.code
        return response
    }

    httpClient.get = function (config) {
        if (typeof config == 'object') {
            config.method = 'GET'
        }
        return this.send(config)
    }

    httpClient.post = function (config) {
        if (typeof config == 'object') {
            config.method = 'POST'
        }
        return this.send(config)
    }

    httpClient.delete = function (config) {
        if (typeof config == 'object') {
            config.method = 'DELETE'
        }
        return this.send(config)
    }

    httpClient.put = function (config) {
        if (typeof config == 'object') {
            config.method = 'PUT'
        }
        return this.send(config)
    }


    if (typeof config !== 'object') {
        return httpClient
    }
    if (typeof config.baseUrl === 'string') {
        httpClient.baseUrl = config.baseUrl
    }
    if (typeof config.headers === 'object') {
        httpClient.headers = []
        let keys = Object.keys(config.headers)
        for (let i = 0; i < keys.length; i++) {
            let key = keys[i]
            let value = config.headers[key]
            if (typeof value === 'string') {
                httpClient.headers.push({
                    key: key,
                    value: value
                })
            } else if (typeof value === 'object' && Array.isArray(value)) {
                for (let j = 0; j < value.length; j++) {
                    if (typeof value[j] == 'string') {
                        httpClient.headers.push({
                            key: key,
                            value: value[j]
                        })
                    }
                }
            }
        }
    }
    if (typeof config.connectTimeout === 'number') {
        httpClient.__okHttpClient__.setConnectTimeout(config.connectTimeout.longValue(), TimeUnit.MILLISECONDS)
    }
    if (typeof config.readTimeout === 'number') {
        httpClient.__okHttpClient__.setReadTimeout(config.readTimeout.longValue(), TimeUnit.MILLISECONDS)
    }
    if (typeof config.writeTimeout === 'number') {
        httpClient.__okHttpClient__.setWriteTimeout(config.writeTimeout.longValue(), TimeUnit.MILLISECONDS)
    }
    if (typeof config.followRedirects === 'boolean') {
        httpClient.__okHttpClient__.setFollowRedirects(config.followRedirects)
    }
    return httpClient
}

module.exports = {
    create: create
}