我试图在极小的系统(Ubuntu 16.04 docker image)上从源代码构建Python 2.7,这不会导致HTTPS下载因if ($customer->getEmail() == '' and @$data['email'] != '') {$customer->setEmail($data['email']);}
而失败。我不想使用包管理器,但我知道这可以轻松解决问题。
我浏览了Unknown url type error in urllib2并将不同的引用补丁应用于<urlopen error unknown url type: https>
,将setup.py
和SSL
中的Modules/Setup
变量设置为我的安装前缀传递给OpenSSL 1.1.1的Modules/Setup.dist
并将./config --prefix
设置为OpenSSL安装前缀。
我怀疑一个这样的最小系统需要修复的东西比其他答案中建议的要多。为什么LD_LIBRARY_PATH
没有--with-ssl
切换?
构建脚本是
configure
我选择了apt-get update && apt-get install --yes wget xz-utils make gcc patch
wget http://www.cpan.org/src/5.0/perl-5.26.1.tar.gz && tar xf perl-5.26.1.tar.gz && cd perl-5.26.1 && ./configure.gnu && make -j16 && make install && cd ..
wget https://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.8.1.tar.xz && tar xf gettext-0.19.8.1.tar.xz && cd gettext-0.19.8.1 && ./configure && make -j16 && make install && cd ..
wget https://www.zlib.net/zlib-1.2.11.tar.gz && tar xf zlib-1.2.11.tar.gz && cd zlib-1.2.11 && ./configure && make -j16 && make install && cd ..
wget https://www.kernel.org/pub/software/scm/git/git-2.13.3.tar.gz && tar xf git-2.13.3.tar.gz && cd git-2.13.3 && ./configure --with-perl=/usr/local/bin/perl && make -j16 && make install && cd ..
# need `--with-perl` passed to `configure` because the `/usr/local/bin/perl` isn't picked up regardless where it's found in PATH, see https://stackoverflow.com/questions/48931247/cant-locate-extutils-makemaker-pm-in-inc-during-git-build for details
wget https://www.openssl.org/source/openssl-1.1.1-pre1.tar.gz && tar xf openssl-1.1.1-pre1.tar.gz && cd openssl-1.1.1-pre1 && ./config --prefix=/usr/local/openssl && make -j16 && make install && cd ..
# need to install into explicit prefix different from `/usr/local` in order to make OpenSSL get picked up by Python's patched `configure` (specifying `OPENSSL_ROOT=/usr/local` doesn't work)
wget https://www.python.org/ftp/python/2.7.14/Python-2.7.14.tgz && tar xf Python-2.7.14.tgz && cd Python-2.7.14 && wget https://gist.githubusercontent.com/rkitover/2d9e5baff1f1cc4f2618dee53083bd35/raw/7f33fcf5470a9f1013ac6ae7bb168368a98fe5a0/python-2.7.14-custom-static-openssl.patch && patch -p1 <python-2.7.14-custom-static-openssl.patch && env OPENSSL_ROOT=/usr/local/openssl ./configure --disable-shared && make -j16 && make install && cd ..
git clone git://git.gnome.org/jhbuild && cd jhbuild && ./autogen.sh --prefix=/usr/local && make && make install && cd ..
env JHBUILD_RUN_AS_ROOT= jhbuild bootstrap
作为测试命令,因为这是预期的结果,可以随意提出更好的结果。
我在https://gitlab.com/krichter/jhbuild-docker-build创建了一个SSCCE,它允许在GitLab CI中运行构建脚本,并且可以在https://gitlab.com/krichter/jhbuild-docker-build/-/jobs/53948513调查包含完整构建日志的示例运行。
答案 0 :(得分:0)
我可以在import org.glassfish.hk2.api.Injectee;
import org.glassfish.hk2.api.InjectionResolver;
import org.glassfish.hk2.api.ServiceHandle;
import org.glassfish.hk2.api.TypeLiteral;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ContainerRequest;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import static org.assertj.core.api.Assertions.assertThat;
public class ForwardHeadersTest extends JerseyTest {
private static final String BASE_URI = "http://localhost:8000";
private static final String TEST_HEADER_NAME = "X-Test-Header";
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface WithHeadersTarget {
String baseUri();
String[] headerNames() default {};
}
@Path("test")
public static class TestResource {
@WithHeadersTarget(
baseUri = BASE_URI
)
private WebTarget target;
@GET
public String get() {
return target.path("client").request().get(String.class);
}
}
@Path("client")
public static class ClientResource {
@GET
public String getReversedHeader(@HeaderParam(TEST_HEADER_NAME) String header) {
System.out.println(header);
return new StringBuilder(header).reverse().toString();
}
}
private static class WithHeadersTargetInjectionResolver
implements InjectionResolver<WithHeadersTarget> {
private final Provider<ContainerRequest> requestProvider;
private final Client client;
@Inject
public WithHeadersTargetInjectionResolver(Provider<ContainerRequest> requestProvider) {
this.requestProvider = requestProvider;
this.client = ClientBuilder.newClient();
}
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> handle) {
if (injectee.getRequiredType() == WebTarget.class
&& injectee.getParent().isAnnotationPresent(WithHeadersTarget.class)) {
WithHeadersTarget anno = injectee.getParent().getAnnotation(WithHeadersTarget.class);
String uri = anno.baseUri();
String[] headersNames = anno.headerNames();
MultivaluedMap<String, String> requestHeaders = requestProvider.get().getRequestHeaders();
return client.target(uri)
.register(new HeadersFilter(requestHeaders, headersNames));
}
return null;
}
@Override
public boolean isConstructorParameterIndicator() {
return false;
}
@Override
public boolean isMethodParameterIndicator() {
return false;
}
private class HeadersFilter implements ClientRequestFilter {
private final MultivaluedMap<String, String> headers;
private final String[] headerNames;
private HeadersFilter(MultivaluedMap<String, String> headers, String[] headerNames) {
this.headers = headers;
this.headerNames = headerNames;
}
@Override
public void filter(ClientRequestContext requestContext) throws IOException {
// if headers names is empty, add all headers
if (this.headerNames.length == 0) {
for (Map.Entry<String, List<String>> entry: this.headers.entrySet()) {
requestContext.getHeaders().put(entry.getKey(), new ArrayList<>(entry.getValue()));
}
// else just add the headers from the annotation
} else {
for (String header: this.headerNames) {
requestContext.getHeaders().put(header, new ArrayList<>(this.headers.get(header)));
}
}
}
}
}
@Override
public ResourceConfig configure() {
return new ResourceConfig()
.register(TestResource.class)
.register(ClientResource.class)
.register(new AbstractBinder() {
@Override
protected void configure() {
bind(WithHeadersTargetInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<WithHeadersTarget>>() {
}).in(Singleton.class);
}
})
.register(new LoggingFilter(Logger.getAnonymousLogger(), true))
.register(new ExceptionMapper<Throwable>() {
@Override
public Response toResponse(Throwable t) {
t.printStackTrace();
return Response.serverError().entity(t.getMessage()).build();
}
});
}
@Override
public URI getBaseUri() {
return URI.create(BASE_URI);
}
@Test
public void testIt() {
final String response = target("test")
.request()
.header(TEST_HEADER_NAME, "HelloWorld")
.get(String.class);
assertThat(response).isEqualTo("dlroWolleH");
}
}
(我在FIXME处理)之后让它失败
<urlopen error [SSL: NO_CIPHERS_AVAILABLE] no ciphers available (_ssl.c:661)>
添加到OpenSSL的--prefix=/usr/local/ --openssldir=/usr/local
,使用
修补config
和Modules/Setup.dist
Modules/Setup
(--- Modules/Setup.dist 2018-02-23 01:12:46.537415323 +0100
+++ Modules/Setup.dist.d 2018-02-23 01:44:45.235092890 +0100
@@ -215,10 +215,10 @@
# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
-#SSL=/usr/local/ssl
-#_ssl _ssl.c \
-# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-# -L$(SSL)/lib -lssl -lcrypto
+SSL=/usr/local
+_ssl _ssl.c \
+ -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
+ -L$(SSL)/lib -lssl -lcrypto
# The crypt module is now disabled by default because it breaks builds
# on many systems (where -lcrypt is needed), e.g. Linux (I believe).
)
可以在https://gitlab.com/krichter/jhbuild-docker-build/-/jobs/53978734找到克服初始错误的示例构建。