Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
da581599
J
jenkins
项目概览
xxadev
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
da581599
编写于
4月 05, 2017
作者:
J
Jesse Glick
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
-http mode broke when the user omitted the mandatory final `/` in the Jenkins URL.
上级
3939820c
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
44 addition
and
29 deletion
+44
-29
cli/src/main/java/hudson/cli/CLI.java
cli/src/main/java/hudson/cli/CLI.java
+16
-16
cli/src/main/java/hudson/cli/CliPort.java
cli/src/main/java/hudson/cli/CliPort.java
+3
-3
cli/src/main/java/hudson/cli/FullDuplexHttpStream.java
cli/src/main/java/hudson/cli/FullDuplexHttpStream.java
+19
-5
test/src/test/java/hudson/cli/CLIActionTest.java
test/src/test/java/hudson/cli/CLIActionTest.java
+4
-3
test/src/test/java/hudson/cli/CLITest.java
test/src/test/java/hudson/cli/CLITest.java
+1
-1
test/src/test/java/jenkins/security/Security218BlackBoxTest.java
...c/test/java/jenkins/security/Security218BlackBoxTest.java
+1
-1
未找到文件。
cli/src/main/java/hudson/cli/CLI.java
浏览文件 @
da581599
...
@@ -146,19 +146,16 @@ public class CLI implements AutoCloseable {
...
@@ -146,19 +146,16 @@ public class CLI implements AutoCloseable {
this
.
authorization
=
factory
.
authorization
;
this
.
authorization
=
factory
.
authorization
;
ExecutorService
exec
=
factory
.
exec
;
ExecutorService
exec
=
factory
.
exec
;
String
url
=
jenkins
.
toExternalForm
();
if
(!
url
.
endsWith
(
"/"
))
url
+=
'/'
;
ownsPool
=
exec
==
null
;
ownsPool
=
exec
==
null
;
pool
=
exec
!=
null
?
exec
:
Executors
.
newCachedThreadPool
(
new
NamingThreadFactory
(
Executors
.
defaultThreadFactory
(),
"CLI.pool"
));
pool
=
exec
!=
null
?
exec
:
Executors
.
newCachedThreadPool
(
new
NamingThreadFactory
(
Executors
.
defaultThreadFactory
(),
"CLI.pool"
));
Channel
_channel
;
Channel
_channel
;
try
{
try
{
_channel
=
connectViaCliPort
(
jenkins
,
getCliTcpPort
(
url
));
_channel
=
connectViaCliPort
(
jenkins
,
getCliTcpPort
(
jenkins
));
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
LOGGER
.
log
(
Level
.
FINE
,
"Failed to connect via CLI port. Falling back to HTTP"
,
e
);
LOGGER
.
log
(
Level
.
FINE
,
"Failed to connect via CLI port. Falling back to HTTP"
,
e
);
try
{
try
{
_channel
=
connectViaHttp
(
url
);
_channel
=
connectViaHttp
(
jenkins
);
}
catch
(
IOException
e2
)
{
}
catch
(
IOException
e2
)
{
e
.
addSuppressed
(
e2
);
e
.
addSuppressed
(
e2
);
throw
e
;
throw
e
;
...
@@ -177,12 +174,11 @@ public class CLI implements AutoCloseable {
...
@@ -177,12 +174,11 @@ public class CLI implements AutoCloseable {
* @deprecated Specific to {@link Mode#REMOTING}.
* @deprecated Specific to {@link Mode#REMOTING}.
*/
*/
@Deprecated
@Deprecated
private
Channel
connectViaHttp
(
String
url
)
throws
IOException
{
private
Channel
connectViaHttp
(
URL
url
)
throws
IOException
{
LOGGER
.
log
(
FINE
,
"Trying to connect to {0} via Remoting over HTTP"
,
url
);
LOGGER
.
log
(
FINE
,
"Trying to connect to {0} via Remoting over HTTP"
,
url
);
URL
jenkins
=
new
URL
(
url
+
"cli?remoting=true"
);
FullDuplexHttpStream
con
=
new
FullDuplexHttpStream
(
jenkins
,
authorization
);
FullDuplexHttpStream
con
=
new
FullDuplexHttpStream
(
url
,
"cli?remoting=true"
,
authorization
);
Channel
ch
=
new
Channel
(
"Chunked connection to "
+
jenkins
,
Channel
ch
=
new
Channel
(
"Chunked connection to "
+
url
,
pool
,
con
.
getInputStream
(),
con
.
getOutputStream
());
pool
,
con
.
getInputStream
(),
con
.
getOutputStream
());
final
long
interval
=
15
*
1000
;
final
long
interval
=
15
*
1000
;
final
long
timeout
=
(
interval
*
3
)
/
4
;
final
long
timeout
=
(
interval
*
3
)
/
4
;
...
@@ -303,13 +299,14 @@ public class CLI implements AutoCloseable {
...
@@ -303,13 +299,14 @@ public class CLI implements AutoCloseable {
/**
/**
* If the server advertises CLI endpoint, returns its location.
* If the server advertises CLI endpoint, returns its location.
* @deprecated Specific to {@link Mode#REMOTING}.
*/
*/
protected
CliPort
getCliTcpPort
(
String
url
)
throws
IOException
{
@Deprecated
URL
_url
=
new
URL
(
url
);
protected
CliPort
getCliTcpPort
(
URL
url
)
throws
IOException
{
if
(
_url
.
getHost
()==
null
||
_
url
.
getHost
().
length
()==
0
)
{
if
(
url
.
getHost
()==
null
||
url
.
getHost
().
length
()==
0
)
{
throw
new
IOException
(
"Invalid URL: "
+
url
);
throw
new
IOException
(
"Invalid URL: "
+
url
);
}
}
URLConnection
head
=
_
url
.
openConnection
();
URLConnection
head
=
url
.
openConnection
();
try
{
try
{
head
.
connect
();
head
.
connect
();
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
...
@@ -561,6 +558,10 @@ public class CLI implements AutoCloseable {
...
@@ -561,6 +558,10 @@ public class CLI implements AutoCloseable {
return
-
1
;
return
-
1
;
}
}
if
(!
url
.
endsWith
(
"/"
))
{
url
+=
'/'
;
}
if
(
args
.
isEmpty
())
if
(
args
.
isEmpty
())
args
=
Arrays
.
asList
(
"help"
);
// default to help
args
=
Arrays
.
asList
(
"help"
);
// default to help
...
@@ -643,7 +644,7 @@ public class CLI implements AutoCloseable {
...
@@ -643,7 +644,7 @@ public class CLI implements AutoCloseable {
private
static
int
sshConnection
(
String
jenkinsUrl
,
String
user
,
List
<
String
>
args
,
PrivateKeyProvider
provider
,
final
boolean
strictHostKey
)
throws
IOException
{
private
static
int
sshConnection
(
String
jenkinsUrl
,
String
user
,
List
<
String
>
args
,
PrivateKeyProvider
provider
,
final
boolean
strictHostKey
)
throws
IOException
{
Logger
.
getLogger
(
SecurityUtils
.
class
.
getName
()).
setLevel
(
Level
.
WARNING
);
// suppress: BouncyCastle not registered, using the default JCE provider
Logger
.
getLogger
(
SecurityUtils
.
class
.
getName
()).
setLevel
(
Level
.
WARNING
);
// suppress: BouncyCastle not registered, using the default JCE provider
URL
url
=
new
URL
(
jenkinsUrl
+
"
/
login"
);
URL
url
=
new
URL
(
jenkinsUrl
+
"login"
);
URLConnection
conn
=
url
.
openConnection
();
URLConnection
conn
=
url
.
openConnection
();
String
endpointDescription
=
conn
.
getHeaderField
(
"X-SSH-Endpoint"
);
String
endpointDescription
=
conn
.
getHeaderField
(
"X-SSH-Endpoint"
);
...
@@ -711,8 +712,7 @@ public class CLI implements AutoCloseable {
...
@@ -711,8 +712,7 @@ public class CLI implements AutoCloseable {
private
static
int
plainHttpConnection
(
String
url
,
List
<
String
>
args
,
CLIConnectionFactory
factory
)
throws
IOException
,
InterruptedException
{
private
static
int
plainHttpConnection
(
String
url
,
List
<
String
>
args
,
CLIConnectionFactory
factory
)
throws
IOException
,
InterruptedException
{
LOGGER
.
log
(
FINE
,
"Trying to connect to {0} via plain protocol over HTTP"
,
url
);
LOGGER
.
log
(
FINE
,
"Trying to connect to {0} via plain protocol over HTTP"
,
url
);
URL
jenkins
=
new
URL
(
url
+
"cli?remoting=false"
);
FullDuplexHttpStream
streams
=
new
FullDuplexHttpStream
(
new
URL
(
url
),
"cli?remoting=false"
,
factory
.
authorization
);
FullDuplexHttpStream
streams
=
new
FullDuplexHttpStream
(
jenkins
,
factory
.
authorization
);
class
ClientSideImpl
extends
PlainCLIProtocol
.
ClientSide
{
class
ClientSideImpl
extends
PlainCLIProtocol
.
ClientSide
{
boolean
complete
;
boolean
complete
;
int
exit
=
-
1
;
int
exit
=
-
1
;
...
...
cli/src/main/java/hudson/cli/CliPort.java
浏览文件 @
da581599
...
@@ -8,8 +8,8 @@ import java.security.KeyFactory;
...
@@ -8,8 +8,8 @@ import java.security.KeyFactory;
import
java.security.PublicKey
;
import
java.security.PublicKey
;
import
java.security.spec.X509EncodedKeySpec
;
import
java.security.spec.X509EncodedKeySpec
;
/**
/**
* @author Kohsuke Kawaguchi
* @deprecated Specific to Remoting mode.
*/
*/
public
final
class
CliPort
{
public
final
class
CliPort
{
/**
/**
...
...
cli/src/main/java/hudson/cli/FullDuplexHttpStream.java
浏览文件 @
da581599
...
@@ -20,7 +20,7 @@ import org.apache.commons.codec.binary.Base64;
...
@@ -20,7 +20,7 @@ import org.apache.commons.codec.binary.Base64;
* @author Kohsuke Kawaguchi
* @author Kohsuke Kawaguchi
*/
*/
public
class
FullDuplexHttpStream
{
public
class
FullDuplexHttpStream
{
private
final
URL
target
;
private
final
URL
base
;
/**
/**
* Authorization header value needed to get through the HTTP layer.
* Authorization header value needed to get through the HTTP layer.
*/
*/
...
@@ -48,16 +48,31 @@ public class FullDuplexHttpStream {
...
@@ -48,16 +48,31 @@ public class FullDuplexHttpStream {
return
null
;
return
null
;
}
}
@Deprecated
public
FullDuplexHttpStream
(
URL
target
,
String
authorization
)
throws
IOException
{
this
(
new
URL
(
target
.
toString
().
replaceFirst
(
"/cli.*$"
,
""
)),
target
.
toString
().
replaceFirst
(
"(.+)/cli.*$"
,
"$1"
),
authorization
);
}
/**
/**
* @param base the base URL of Jenkins
* @param target
* @param target
* The endpoint that we are making requests to.
* The endpoint that we are making requests to.
* @param authorization
* @param authorization
* The value of the authorization header, if non-null.
* The value of the authorization header, if non-null.
*/
*/
public
FullDuplexHttpStream
(
URL
target
,
String
authorization
)
throws
IOException
{
public
FullDuplexHttpStream
(
URL
base
,
String
relativeTarget
,
String
authorization
)
throws
IOException
{
this
.
target
=
target
;
if
(!
base
.
toString
().
endsWith
(
"/"
))
{
throw
new
IllegalArgumentException
(
base
.
toString
());
}
if
(
relativeTarget
.
startsWith
(
"/"
))
{
throw
new
IllegalArgumentException
(
relativeTarget
);
}
this
.
base
=
base
;
this
.
authorization
=
authorization
;
this
.
authorization
=
authorization
;
URL
target
=
new
URL
(
base
,
relativeTarget
);
CrumbData
crumbData
=
new
CrumbData
();
CrumbData
crumbData
=
new
CrumbData
();
UUID
uuid
=
UUID
.
randomUUID
();
// so that the server can correlate those two connections
UUID
uuid
=
UUID
.
randomUUID
();
// so that the server can correlate those two connections
...
@@ -128,8 +143,7 @@ public class FullDuplexHttpStream {
...
@@ -128,8 +143,7 @@ public class FullDuplexHttpStream {
}
}
private
String
createCrumbUrlBase
()
{
private
String
createCrumbUrlBase
()
{
String
url
=
target
.
toExternalForm
();
return
base
+
"crumbIssuer/api/xml/"
;
return
new
StringBuilder
(
url
.
substring
(
0
,
url
.
lastIndexOf
(
"/cli"
))).
append
(
"/crumbIssuer/api/xml/"
).
toString
();
}
}
private
String
readData
(
String
dest
)
throws
IOException
{
private
String
readData
(
String
dest
)
throws
IOException
{
...
...
test/src/test/java/hudson/cli/CLIActionTest.java
浏览文件 @
da581599
...
@@ -68,7 +68,7 @@ public class CLIActionTest {
...
@@ -68,7 +68,7 @@ public class CLIActionTest {
public
void
testDuplexHttp
()
throws
Exception
{
public
void
testDuplexHttp
()
throws
Exception
{
pool
=
Executors
.
newCachedThreadPool
();
pool
=
Executors
.
newCachedThreadPool
();
try
{
try
{
FullDuplexHttpStream
con
=
new
FullDuplexHttpStream
(
new
URL
(
j
.
getURL
(),
"cli"
)
,
null
);
FullDuplexHttpStream
con
=
new
FullDuplexHttpStream
(
j
.
getURL
(),
"cli"
,
null
);
Channel
ch
=
new
ChannelBuilder
(
"test connection"
,
pool
).
build
(
con
.
getInputStream
(),
con
.
getOutputStream
());
Channel
ch
=
new
ChannelBuilder
(
"test connection"
,
pool
).
build
(
con
.
getInputStream
(),
con
.
getOutputStream
());
ch
.
close
();
ch
.
close
();
}
finally
{
}
finally
{
...
@@ -80,7 +80,7 @@ public class CLIActionTest {
...
@@ -80,7 +80,7 @@ public class CLIActionTest {
public
void
security218
()
throws
Exception
{
public
void
security218
()
throws
Exception
{
pool
=
Executors
.
newCachedThreadPool
();
pool
=
Executors
.
newCachedThreadPool
();
try
{
try
{
FullDuplexHttpStream
con
=
new
FullDuplexHttpStream
(
new
URL
(
j
.
getURL
(),
"cli"
)
,
null
);
FullDuplexHttpStream
con
=
new
FullDuplexHttpStream
(
j
.
getURL
(),
"cli"
,
null
);
Channel
ch
=
new
ChannelBuilder
(
"test connection"
,
pool
).
build
(
con
.
getInputStream
(),
con
.
getOutputStream
());
Channel
ch
=
new
ChannelBuilder
(
"test connection"
,
pool
).
build
(
con
.
getInputStream
(),
con
.
getOutputStream
());
ch
.
call
(
new
Security218
());
ch
.
call
(
new
Security218
());
fail
(
"Expected the call to be rejected"
);
fail
(
"Expected the call to be rejected"
);
...
@@ -241,7 +241,8 @@ public class CLIActionTest {
...
@@ -241,7 +241,8 @@ public class CLIActionTest {
FileUtils
.
copyURLToFile
(
j
.
jenkins
.
getJnlpJars
(
"jenkins-cli.jar"
).
getURL
(),
jar
);
FileUtils
.
copyURLToFile
(
j
.
jenkins
.
getJnlpJars
(
"jenkins-cli.jar"
).
getURL
(),
jar
);
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
assertEquals
(
0
,
new
Launcher
.
LocalLauncher
(
StreamTaskListener
.
fromStderr
()).
launch
().
cmds
(
assertEquals
(
0
,
new
Launcher
.
LocalLauncher
(
StreamTaskListener
.
fromStderr
()).
launch
().
cmds
(
"java"
,
"-Dfile.encoding=ISO-8859-2"
,
"-Duser.language=cs"
,
"-Duser.country=CZ"
,
"-jar"
,
jar
.
getAbsolutePath
(),
"-s"
,
j
.
getURL
().
toString
(),
"-noKeyAuth"
,
"test-diagnostic"
).
"java"
,
"-Dfile.encoding=ISO-8859-2"
,
"-Duser.language=cs"
,
"-Duser.country=CZ"
,
"-jar"
,
jar
.
getAbsolutePath
(),
"-s"
,
j
.
getURL
().
toString
().
/* just checking */
replaceFirst
(
"/$"
,
""
),
"-noKeyAuth"
,
"test-diagnostic"
).
stdout
(
baos
).
stderr
(
System
.
err
).
join
());
stdout
(
baos
).
stderr
(
System
.
err
).
join
());
assertEquals
(
"encoding=ISO-8859-2 locale=cs_CZ"
,
baos
.
toString
().
trim
());
assertEquals
(
"encoding=ISO-8859-2 locale=cs_CZ"
,
baos
.
toString
().
trim
());
// TODO test that stdout/stderr are in expected encoding (not true of -remoting mode!)
// TODO test that stdout/stderr are in expected encoding (not true of -remoting mode!)
...
...
test/src/test/java/hudson/cli/CLITest.java
浏览文件 @
da581599
...
@@ -109,7 +109,7 @@ public class CLITest {
...
@@ -109,7 +109,7 @@ public class CLITest {
assertThat
(
baos
.
toString
(),
containsString
(
"Authenticated as: admin"
));
assertThat
(
baos
.
toString
(),
containsString
(
"Authenticated as: admin"
));
baos
=
new
ByteArrayOutputStream
();
baos
=
new
ByteArrayOutputStream
();
assertEquals
(
0
,
new
Launcher
.
LocalLauncher
(
StreamTaskListener
.
fromStderr
()).
launch
().
cmds
(
assertEquals
(
0
,
new
Launcher
.
LocalLauncher
(
StreamTaskListener
.
fromStderr
()).
launch
().
cmds
(
"java"
,
"-Duser.home="
+
home
,
"-jar"
,
jar
.
getAbsolutePath
(),
"-s"
,
r
.
getURL
().
toString
(),
"-ssh"
,
"-user"
,
"admin"
,
"-i"
,
privkey
.
getAbsolutePath
(),
"-strictHostKey"
,
"who-am-i"
"java"
,
"-Duser.home="
+
home
,
"-jar"
,
jar
.
getAbsolutePath
(),
"-s"
,
r
.
getURL
().
toString
()
.
/* just checking */
replaceFirst
(
"/$"
,
""
)
,
"-ssh"
,
"-user"
,
"admin"
,
"-i"
,
privkey
.
getAbsolutePath
(),
"-strictHostKey"
,
"who-am-i"
).
stdout
(
baos
).
stderr
(
System
.
err
).
join
());
).
stdout
(
baos
).
stderr
(
System
.
err
).
join
());
assertThat
(
baos
.
toString
(),
containsString
(
"Authenticated as: admin"
));
assertThat
(
baos
.
toString
(),
containsString
(
"Authenticated as: admin"
));
}
}
...
...
test/src/test/java/jenkins/security/Security218BlackBoxTest.java
浏览文件 @
da581599
...
@@ -277,7 +277,7 @@ public class Security218BlackBoxTest {
...
@@ -277,7 +277,7 @@ public class Security218BlackBoxTest {
try
{
try
{
CLI
cli
=
new
CLI
(
r
.
getURL
())
{
CLI
cli
=
new
CLI
(
r
.
getURL
())
{
@Override
@Override
protected
CliPort
getCliTcpPort
(
String
url
)
throws
IOException
{
protected
CliPort
getCliTcpPort
(
URL
url
)
throws
IOException
{
return
new
CliPort
(
new
InetSocketAddress
(
proxySocket
.
getInetAddress
(),
proxySocket
.
getLocalPort
()),
/* ignore identity */
null
,
1
);
return
new
CliPort
(
new
InetSocketAddress
(
proxySocket
.
getInetAddress
(),
proxySocket
.
getLocalPort
()),
/* ignore identity */
null
,
1
);
}
}
};
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录