All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cloud.chain.git.api.service.impl.GitHubServiceImpl Maven / Gradle / Ivy

The newest version!
package cloud.chain.git.api.service.impl;

import cloud.chain.git.api.dto.*;
import cloud.chain.git.api.http.HttpClient;
import cloud.chain.git.api.service.GitApiService;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * wuXiaoMing
 * 2023/2/19 11:20
 */
@Component
@Slf4j
@ConditionalOnProperty("github.token")
@ConfigurationProperties(prefix = "github")
@Data
public class GitHubServiceImpl implements GitApiService {

    private static final String CONTENT_TYPE = "application/json; charset=utf-8";
    private static final String GIT_HUB_URL = "https://api.github.com/";
    private final OkHttpClient client = HttpClient.getClient();
    private String token;

    @Override
    public Res getRepositoryContent(ReposInfo reposInfo) {
        return getRepositoryContent(reposInfo, null);
    }

    @SneakyThrows
    @Override
    public Res getRepositoryContent(ReposInfo reposInfo, Map headers) {
        String url = formatUrl(reposInfo);
        Request.Builder builder = new Request.Builder();
        builder.url(url);
        confHeader(builder, headers);
        Response response = client.newCall(builder.build()).execute();
        return new Res(response);
    }

    @SneakyThrows
    @Override
    public Res createARepositoryForTheAuthenticatedUser(Repos repos) {
        Request.Builder builder = new Request.Builder();
        RequestBody body = RequestBody.create(MediaType.parse(CONTENT_TYPE),
                JSON.toJSONString(repos));
        builder.url("https://api.github.com/user/repos")
                .post(body);
        confHeader(builder, Collections.emptyMap());
        Response response = client.newCall(builder.build()).execute();
        return new Res(response);
    }

    @SneakyThrows
    @Override
    public Res createOrUpdateFileContents(ReposFileInfo reposFileInfo, ReposInfo reposInfo) {
        Request.Builder builder = new Request.Builder();
        String url = formatUrl(reposInfo);
        RequestBody body = RequestBody.create(MediaType.parse(CONTENT_TYPE),
                JSON.toJSONString(reposFileInfo));
        builder.url(url)
                .put(body);
        confHeader(builder, Collections.emptyMap());
        Response response = client.newCall(builder.build()).execute();
        return new Res(response);
    }

    @SneakyThrows
    @Override
    public Res deleteAFile(ReposDeleteInfo reposDeleteInfo, ReposInfo reposInfo) {
        Request.Builder builder = new Request.Builder();
        String url = formatUrl(reposInfo);
        RequestBody body = RequestBody.create(MediaType.parse(CONTENT_TYPE),
                JSON.toJSONString(reposDeleteInfo));
        builder.url(url)
                .delete(body);
        confHeader(builder, Collections.emptyMap());
        Response response = client.newCall(builder.build()).execute();
        return new Res(response);
    }

    @SneakyThrows
    @Override
    public void proxy(String path, HttpServletRequest request, HttpServletResponse response) {
        String url = GIT_HUB_URL + path + getQueryString(request);
        String method = request.getMethod();
        Request.Builder builder = new Request.Builder();
        builder.url(url);
        builder.headers(getHeaders(request));
        RequestBody body = getRequestBody(request);
        builder.method(method, body);
        confHeader(builder, request);
        Response res = client.newCall(builder.build()).execute();
        byte[] bytes = res.body().bytes();
        response.setStatus(res.code());
        ServletOutputStream out = response.getOutputStream();
        out.write(bytes);
        response.flushBuffer();
    }

    private String formatUrl(ReposInfo reposInfo) {
        return String.format("https://api.github.com/repos/%s/%s/contents/%s",
                reposInfo.getOwner(),
                reposInfo.getRepo(),
                reposInfo.getPath()
        );
    }

    private void confHeader(Request.Builder builder, HttpServletRequest request) {
        Enumeration names = request.getHeaderNames();
        if (ObjectUtils.isEmpty(names)) {
            return;
        }
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if ("accept-encoding".equalsIgnoreCase(name)
                    || "host".equalsIgnoreCase(name)
                    || "connection".equalsIgnoreCase(name)) {
                continue;
            }
            String value = request.getHeader(name);
            builder.addHeader(name, value);
        }
        if (StringUtils.hasText(token)) {
            builder.addHeader("Authorization", String.format("Bearer %s", token));
        }
        builder.addHeader("X-GitHub-Api-Version", "2022-11-28")
                .addHeader("Accept", "application/vnd.github+json");
    }


    private void confHeader(Request.Builder builder, Map map) {
        if (!ObjectUtils.isEmpty(map)) {
            builder.headers(Headers.of(map));
        }
        if (StringUtils.hasText(token)) {
            builder.addHeader("Authorization", String.format("Bearer %s", token));
        }
        builder.addHeader("X-GitHub-Api-Version", "2022-11-28")
                .addHeader("Accept", "application/vnd.github+json");
    }

    /**
     * 获取转发头部
     *
     * @param request
     * @return
     */
    private Headers getHeaders(HttpServletRequest request) {
        Headers.Builder builder = new Headers.Builder();
        Enumeration names = request.getHeaderNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if ("accept-encoding".equalsIgnoreCase(name)
                    || "host".equalsIgnoreCase(name)
                    || "connection".equalsIgnoreCase(name)) {
                continue;
            }
            String value = request.getHeader(name);
            builder.add(name, value);
        }
        return builder.build();
    }

    /**
     * 获取请求参数
     *
     * @param request
     * @return
     */
    private String getQueryString(HttpServletRequest request) {
        Map queries = request.getParameterMap();
        if (queries.isEmpty()) {
            return "";
        }
        String str = queries.keySet().stream().map(it ->
                new StringJoiner("=")
                        .add(it)
                        .add(Arrays.stream(queries.get(it)).collect(Collectors.joining(",")))
                        .toString()
        ).collect(Collectors.joining("&"));
        return "?" + str;
    }

    /**
     * 获取请求body
     *
     * @param request
     * @return
     */
    @SneakyThrows
    private RequestBody getRequestBody(HttpServletRequest request) {
        String type = request.getHeader("content-type");
        if ("get".equalsIgnoreCase(request.getMethod())) {
            return null;
        }
        if (StringUtils.isEmpty(type)) {
            return RequestBody.create(null, "");
        }
        RequestBody body;
        // 文件上传
        if (ServletFileUpload.isMultipartContent(request)) {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultiValueMap fileMap = multipartRequest.getMultiFileMap();
            Map params = multipartRequest.getParameterMap();
            if (!fileMap.isEmpty()) {
                MultipartBody.Builder builder = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM);
                fileMap.entrySet().stream().forEach(it -> {
                    try {
                        builder.addFormDataPart(
                                it.getKey().trim(),
                                it.getValue().get(0).getOriginalFilename(),
                                RequestBody.create(
                                        MediaType.parse(it.getValue().get(0).getContentType()),
                                        it.getValue().get(0).getBytes()
                                )
                        );
                    } catch (IOException e) {
                        log.error("form request error -->", e);
                    }
                });
                params.entrySet().stream().forEach(it -> {
                    builder.addFormDataPart(
                            it.getKey(),
                            Arrays.stream(it.getValue()).distinct().collect(Collectors.joining(","))
                    );
                });
                body = builder.build();
            } else {
                FormBody.Builder builder = new FormBody.Builder();
                params.entrySet().stream().forEach(it -> {
                    builder.add(
                            it.getKey(),
                            Arrays.stream(it.getValue()).distinct().collect(Collectors.joining(","))
                    );
                });
                body = builder.build();
            }

        }
        // 非文件上传
        else {
            DataInputStream in = new DataInputStream(request.getInputStream());
            int size = request.getContentLength();
            byte[] bytes = new byte[size];
            in.readFully(bytes);
            in.close();
            log.info("size: {}, body --> \n {}", size, new String(bytes));
            body = RequestBody.create(
                    MediaType.parse(type),
                    bytes
            );
        }
        return body;
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy