Skip to content

Commit

Permalink
test: update tests in com.itangcent.http (#500)
Browse files Browse the repository at this point in the history
  • Loading branch information
tangcent authored Jun 7, 2021
1 parent 5c1d927 commit ecfd8bb
Show file tree
Hide file tree
Showing 10 changed files with 930 additions and 424 deletions.
10 changes: 10 additions & 0 deletions common-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ dependencies {
// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
compileOnly group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.10'

// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime
testImplementation group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.10'

// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
testImplementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.10'

// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
testImplementation "org.junit.jupiter:junit-jupiter-api:${junit_version}"
Expand All @@ -50,7 +55,12 @@ dependencies {
// https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
testImplementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.10'

// https://search.maven.org/artifact/org.mockito.kotlin/mockito-kotlin/3.2.0/jar
testImplementation 'org.mockito.kotlin:mockito-kotlin:3.2.0'

// https://mvnrepository.com/artifact/org.mockito/mockito-inline
testImplementation group: 'org.mockito', name: 'mockito-inline', version: '3.11.0'

}


Expand Down
109 changes: 57 additions & 52 deletions common-api/src/main/kotlin/com/itangcent/http/ApacheHttpClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,23 @@ open class ApacheHttpClient : HttpClient {
this.apacheCookieStore = ApacheCookieStore(basicCookieStore)
this.httpClientContext!!.cookieStore = basicCookieStore
this.httpClient = HttpClients.custom()
.setConnectionManager(PoolingHttpClientConnectionManager().also {
it.maxTotal = 50
it.defaultMaxPerRoute = 20
})
.setDefaultSocketConfig(SocketConfig.custom()
.setSoTimeout(30 * 1000)
.build())
.setDefaultRequestConfig(RequestConfig.custom()
.setConnectTimeout(30 * 1000)
.setConnectionRequestTimeout(30 * 1000)
.setSocketTimeout(30 * 1000)
.setCookieSpec(CookieSpecs.STANDARD).build())
.build()
.setConnectionManager(PoolingHttpClientConnectionManager().also {
it.maxTotal = 50
it.defaultMaxPerRoute = 20
})
.setDefaultSocketConfig(
SocketConfig.custom()
.setSoTimeout(30 * 1000)
.build()
)
.setDefaultRequestConfig(
RequestConfig.custom()
.setConnectTimeout(30 * 1000)
.setConnectionRequestTimeout(30 * 1000)
.setSocketTimeout(30 * 1000)
.setCookieSpec(CookieSpecs.STANDARD).build()
)
.build()
}

constructor(httpClient: org.apache.http.client.HttpClient) {
Expand Down Expand Up @@ -92,54 +96,54 @@ open class ApacheHttpClient : HttpClient {
}

val requestBuilder = RequestBuilder.create(request.method())
.setUri(url)
.setUri(url)

request.headers()?.forEach {
requestBuilder.addHeader(it.name(), it.value())
}

if (request.method().toUpperCase() != "GET") {

var requestEntity: HttpEntity? = null
if (request.params().notNullOrEmpty()) {
if (request.contentType()?.startsWith("application/x-www-form-urlencoded") != true) {
if (request.contentType()?.startsWith("multipart/form-data") == true) {
val entityBuilder = MultipartEntityBuilder.create()
for (param in request.params()!!) {
if (param.type() == "file") {
val filePath = param.value()
if (filePath.isNullOrBlank()) {
continue
}
val file = File(filePath)
if (!file.exists() || !file.isFile) {
throw FileNotFoundException("[$filePath] not exist")
}
entityBuilder.addBinaryBody(param.name(), file)
} else {
entityBuilder.addTextBody(param.name(), param.value())
}
}
val boundary = com.itangcent.common.http.EntityUtils.generateBoundary()
entityBuilder.setBoundary(boundary)
//set boundary to header
requestBuilder.setHeader("Content-type", "multipart/form-data; boundary=$boundary")
requestEntity = entityBuilder.build()
}
} else {
if (request.contentType()?.startsWith("application/x-www-form-urlencoded") == true) {
val nameValuePairs: ArrayList<NameValuePair> = ArrayList()
for (param in request.params()!!) {
nameValuePairs.add(BasicNameValuePair(param.name(), param.value()))
}
requestEntity = UrlEncodedFormEntity(nameValuePairs)
} else if (request.contentType()?.startsWith("multipart/form-data") == true) {
val entityBuilder = MultipartEntityBuilder.create()
for (param in request.params()!!) {
if (param.type() == "file") {
val filePath = param.value()
if (filePath.isNullOrBlank()) {
continue
}
val file = File(filePath)
if (!file.exists() || !file.isFile) {
throw FileNotFoundException("[$filePath] not exist")
}
entityBuilder.addBinaryBody(param.name(), file)
} else {
entityBuilder.addTextBody(param.name(), param.value())
}
}
val boundary = com.itangcent.common.http.EntityUtils.generateBoundary()
entityBuilder.setBoundary(boundary)
//set boundary to header
requestBuilder.setHeader("Content-type", "multipart/form-data; boundary=$boundary")
requestEntity = entityBuilder.build()
}
}
if (request.body() != null) {
if (requestEntity != null) {
SpiUtils.loadService(ILogger::class)?.warn("The request with a body should not set content-type:${request.contentType()}")
SpiUtils.loadService(ILogger::class)
?.warn("The request with a body should not set content-type:${request.contentType()}")
}
requestEntity = StringEntity(request.body().toJson(),
ContentType.APPLICATION_JSON)
requestEntity = StringEntity(
request.body().toJson(),
ContentType.APPLICATION_JSON
)
}
if (requestEntity != null) {
requestBuilder.entity = requestEntity
Expand Down Expand Up @@ -207,8 +211,8 @@ class ApacheCookieStore : CookieStore {
* @param cookies the [Cookie]s to be added
*/
override fun addCookies(cookies: Array<Cookie>?) {
cookies?.mapNotNull { cookie -> cookie.asApacheCookie() }
?.forEach { cookieStore.addCookie(it) }
cookies?.map { cookie -> cookie.asApacheCookie() }
?.forEach { cookieStore.addCookie(it) }
}

/**
Expand Down Expand Up @@ -237,8 +241,9 @@ class ApacheCookieStore : CookieStore {
*/
@ScriptTypeName("response")
class ApacheHttpResponse(
val request: HttpRequest,
val response: org.apache.http.HttpResponse) : AbstractHttpResponse() {
private val request: HttpRequest,
private val response: org.apache.http.HttpResponse
) : AbstractHttpResponse() {

/**
* Obtains the status of this response.
Expand Down Expand Up @@ -382,11 +387,11 @@ fun Cookie.asApacheCookie(): org.apache.http.cookie.Cookie {
return this.getWrapper()
}
val cookie =
if (this.getPorts() == null || this.getCommentURL() == null) {
BasicClientCookie(this.getName(), this.getValue())
} else {
BasicClientCookie2(this.getName(), this.getValue())
}
if (this.getPorts() == null || this.getCommentURL() == null) {
BasicClientCookie(this.getName(), this.getValue())
} else {
BasicClientCookie2(this.getName(), this.getValue())
}
cookie.comment = this.getComment()
cookie.domain = this.getDomain()
cookie.path = this.getPath()
Expand Down
68 changes: 33 additions & 35 deletions common-api/src/main/kotlin/com/itangcent/http/HttpRequest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,9 @@ abstract class AbstractHttpRequest : HttpRequest {
*/
override fun headers(headerName: String): Array<String>? {
return headers
?.filter { it.name().equalIgnoreCase(headerName) }
?.mapNotNull { it.value() }
?.toTypedArray()
?.filter { it.name().equalIgnoreCase(headerName) }
?.mapNotNull { it.value() }
?.toTypedArray()
}

/**
Expand All @@ -581,9 +581,9 @@ abstract class AbstractHttpRequest : HttpRequest {
*/
override fun firstHeader(headerName: String): String? {
return headers
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.first { it != null }
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.first { it != null }
}

/**
Expand All @@ -596,9 +596,9 @@ abstract class AbstractHttpRequest : HttpRequest {
*/
override fun lastHeader(headerName: String): String? {
return headers
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.last { it != null }
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.last { it != null }
}

/**
Expand Down Expand Up @@ -803,8 +803,8 @@ abstract class AbstractHttpRequest : HttpRequest {
*/
override fun params(paramName: String): Array<HttpParam>? {
return form
?.filter { it.name() == paramName }
?.toTypedArray()
?.filter { it.name() == paramName }
?.toTypedArray()
}

/**
Expand All @@ -819,11 +819,11 @@ abstract class AbstractHttpRequest : HttpRequest {
*/
override fun paramValues(paramName: String): Array<String>? {
return form
?.filter { it.name() == paramName }
?.map { it.value() }
?.filter { it != null }
?.map { it as String }
?.toTypedArray()
?.filter { it.name() == paramName }
?.map { it.value() }
?.filter { it != null }
?.map { it as String }
?.toTypedArray()
}

override fun firstParam(paramName: String): HttpParam? {
Expand All @@ -832,9 +832,9 @@ abstract class AbstractHttpRequest : HttpRequest {

override fun firstParamValue(paramName: String): String? {
return form
?.filter { it.name() == paramName }
?.map { it.value() }
?.first { it != null }
?.filter { it.name() == paramName }
?.map { it.value() }
?.first { it != null }
}

override fun lastParam(paramName: String): HttpParam? {
Expand All @@ -843,9 +843,9 @@ abstract class AbstractHttpRequest : HttpRequest {

override fun lastParamValue(paramName: String): String? {
return form
?.filter { it.name() == paramName }
?.map { it.value() }
?.last { it != null }
?.filter { it.name() == paramName }
?.map { it.value() }
?.last { it != null }
}

/**
Expand Down Expand Up @@ -996,7 +996,7 @@ fun HttpResponse.getHeaderFileName(): String? {
val candidates = fileName.split("; ")
for (candidate in candidates) {
fileName = candidate.substringAfter("filename=")
.removeSurrounding("\"")
.removeSurrounding("\"")
if (fileName.isNotBlank()) return fileName
}

Expand Down Expand Up @@ -1041,11 +1041,9 @@ abstract class AbstractHttpResponse : HttpResponse {
*/
override fun headers(headerName: String): Array<String>? {
return headers()
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.filter { it != null }
?.map { it as String }
?.toTypedArray()
?.filter { it.name().equalIgnoreCase(headerName) }
?.mapNotNull { it.value() }
?.toTypedArray()
}

/**
Expand All @@ -1058,9 +1056,9 @@ abstract class AbstractHttpResponse : HttpResponse {
*/
override fun firstHeader(headerName: String): String? {
return headers()
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.first { it != null }
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.firstOrNull { it != null }
}

/**
Expand All @@ -1073,9 +1071,9 @@ abstract class AbstractHttpResponse : HttpResponse {
*/
override fun lastHeader(headerName: String): String? {
return headers()
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.last { it != null }
?.filter { it.name().equalIgnoreCase(headerName) }
?.map { it.value() }
?.lastOrNull { it != null }
}

/**
Expand All @@ -1086,7 +1084,7 @@ abstract class AbstractHttpResponse : HttpResponse {
*/
override fun string(): String? {
val charset: Charset? = KitUtils.safe { ContentType.parse(this.contentType())?.charset }
?: Consts.UTF_8
?: Consts.UTF_8
return this.string(charset!!)
}

Expand Down
6 changes: 3 additions & 3 deletions common-api/src/main/kotlin/com/itangcent/http/RequestUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ object RequestUtils {

fun url(): String {
val sb = StringBuilder()
.append(this.protocol ?: "http")
.append("://")
.append(host!!.removeSuffix("?/"))
.append(this.protocol ?: "http")
.append("://")
.append(host!!.removeSuffix("?/"))
if (path.notNullOrBlank()) {
sb.append("/")
sb.append(path!!.removePrefix("/").removeSuffix("?"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.itangcent.common.http

import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test

internal class EntityUtilsTest {

@Test
fun generateBoundary() {
val set = HashSet<String>()
for (i in 0..100) {
val boundary = EntityUtils.generateBoundary()
assertNotNull(boundary)
//length of boundary should be a random size from 30 to 40
assertTrue(boundary.length >= 30)
assertTrue(boundary.length <= 40)
assertTrue(set.add(boundary))
}
}
}
Loading

0 comments on commit ecfd8bb

Please sign in to comment.