Skip to content

Commit 5629597

Browse files
committed
Added Unix Socket Support, JavaPHP now requires Java 17 or above
1 parent 296e45a commit 5629597

File tree

12 files changed

+268
-115
lines changed

12 files changed

+268
-115
lines changed

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CODE_OF_CONDUCT.md

100644100755
File mode changed.

CONTRIBUTING.md

100644100755
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ If you have skills in Java you can contribute as much as you want !
99

1010
### Get Started
1111
- Fork the repository
12-
- Do what you want add or modify
12+
- Do what you want to add or modify
1313
- Do a Pull Request
1414

1515
Note: Modifications of Markdown files, LICENSE, or any files that aren't code does not count !

SECURITY.md

100644100755
File mode changed.

index.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
$body = file_get_contents("php://input");
3+
4+
echo $body;

pom.xml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,33 @@
66

77
<groupId>fr.breadeater</groupId>
88
<artifactId>JavaPHP</artifactId>
9-
<version>2.0-RELEASE</version>
9+
<version>2.2.1</version>
1010

1111
<properties>
12-
<maven.compiler.source>11</maven.compiler.source>
13-
<maven.compiler.target>11</maven.compiler.target>
12+
<maven.compiler.source>17</maven.compiler.source>
13+
<maven.compiler.target>17</maven.compiler.target>
1414
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1515
</properties>
1616

17+
<distributionManagement>
18+
<repository>
19+
<id>github</id>
20+
<name>GitHub Packages</name>
21+
<url>https://maven.pkg.github.com/BreadEaterYT/JavaPHP</url>
22+
</repository>
23+
</distributionManagement>
24+
25+
<build>
26+
<plugins>
27+
<plugin>
28+
<groupId>org.apache.maven.plugins</groupId>
29+
<artifactId>maven-compiler-plugin</artifactId>
30+
<configuration>
31+
<source>17</source>
32+
<target>17</target>
33+
</configuration>
34+
</plugin>
35+
</plugins>
36+
</build>
37+
1738
</project>

src/main/java/fr/breadeater/javaphp/FastCGIUtils.java

Lines changed: 124 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
package fr.breadeater.javaphp;
22

3+
import com.sun.net.httpserver.Headers;
4+
35
import java.io.ByteArrayOutputStream;
46
import java.io.InputStream;
5-
import java.net.Socket;
67
import java.nio.ByteBuffer;
8+
import java.nio.channels.SocketChannel;
79
import java.nio.charset.StandardCharsets;
10+
import java.util.HashMap;
11+
import java.util.List;
812
import java.util.Map;
913

1014
class FastCGIUtils {
11-
public static byte[] buildRecord(Status type, int requestId, byte[] content){
15+
/**
16+
* Builds record and returns it
17+
* @param type The record type
18+
* @param requestId The request ID
19+
* @param content The content
20+
* @return The built record
21+
*/
22+
static byte[] buildRecord(Status type, int requestId, byte[] content){
1223
int length = content.length;
1324
int padding = (8 - (length % 8)) % 8;
1425

@@ -29,7 +40,13 @@ public static byte[] buildRecord(Status type, int requestId, byte[] content){
2940
return buffer.array();
3041
}
3142

32-
public static byte[] encodeLength(int length){
43+
44+
/**
45+
* Encodes byte array length to be sent to FastCGI server
46+
* @param length The length to be encoded.
47+
* @return A byte array containing the encoded length
48+
*/
49+
static byte[] encodeLength(int length){
3350
if (length < 128) return new byte[]{ (byte) length };
3451

3552
return new byte[]{
@@ -40,33 +57,63 @@ public static byte[] encodeLength(int length){
4057
};
4158
}
4259

43-
public static byte[] buildParams(boolean empty, int requestId, Map<String, String> params) throws Exception {
60+
61+
/**
62+
* Build params and sends them to FastCGI server
63+
* @param empty Should it sends Empty Params
64+
* @param requestId
65+
* @param params
66+
* @return
67+
* @throws Exception
68+
*/
69+
static byte[] buildParams(boolean empty, int requestId, Map<String, String> params) throws Exception {
4470
if (empty) return buildRecord(Status.FCGI_PARAMS, requestId, new byte[0]);
4571

4672
ByteArrayOutputStream out = new ByteArrayOutputStream();
4773

4874
for (Map.Entry<String, String> entry : params.entrySet()){
49-
byte[] key = entry.getKey().getBytes(StandardCharsets.UTF_8);
50-
byte[] value = entry.getValue().getBytes(StandardCharsets.UTF_8);
75+
String key = entry.getKey();
76+
String value = entry.getValue();
5177

52-
out.write(encodeLength(key.length));
53-
out.write(encodeLength(value.length));
54-
out.write(key);
55-
out.write(value);
78+
if (value == null) continue;
79+
80+
out.write(encodeLength(key.getBytes(StandardCharsets.UTF_8).length));
81+
out.write(encodeLength(value.getBytes(StandardCharsets.UTF_8).length));
82+
out.write(key.getBytes(StandardCharsets.UTF_8));
83+
out.write(value.getBytes(StandardCharsets.UTF_8));
5684
}
5785

5886
return buildRecord(Status.FCGI_PARAMS, requestId, out.toByteArray());
5987
}
6088

61-
public static byte[] buildStdin(int requestId, byte[] body){
89+
90+
/**
91+
* Builds stdin containing a byte array and returns it
92+
* @param requestId The request ID
93+
* @param body
94+
* @return The built stdin
95+
*/
96+
static byte[] buildStdin(int requestId, byte[] body){
6297
return buildRecord(Status.FCGI_STDIN, requestId, body);
6398
}
6499

65-
public static byte[] buildEmptyStdin(int requestId){
100+
101+
/**
102+
* Builds a empty stdin and returns it
103+
* @param requestId The request ID
104+
* @return The built stdin
105+
*/
106+
static byte[] buildEmptyStdin(int requestId){
66107
return buildRecord(Status.FCGI_STDIN, requestId, new byte[0]);
67108
}
68109

69-
public static byte[] buildRequest(int requestId){
110+
111+
/**
112+
* Builds request and returns it
113+
* @param requestId The request ID
114+
* @return The request
115+
*/
116+
static byte[] buildRequest(int requestId){
70117
byte[] body = new byte[8];
71118

72119
body[0] = 0;
@@ -76,10 +123,17 @@ public static byte[] buildRequest(int requestId){
76123
return buildRecord(Status.FCGI_BEGIN_REQUEST, requestId, body);
77124
}
78125

79-
public static String parseFastCGIRequest(Socket client, InputStream in) throws Exception {
126+
127+
/**
128+
* Parses the FastCGI response and return its body
129+
* @param client The client socket
130+
* @param in The input stream of the client
131+
* @return The body of the response
132+
*/
133+
static String parseFastCGIRequest(SocketChannel client, InputStream in) throws Exception {
80134
String result = null;
81135

82-
while (!client.isClosed()){
136+
while (client.isOpen()){
83137
int version = in.read();
84138
int type = in.read();
85139
int requestIdHigh = in.read();
@@ -112,4 +166,59 @@ public static String parseFastCGIRequest(Socket client, InputStream in) throws E
112166

113167
return result;
114168
}
169+
170+
171+
/**
172+
* Sets all FastCGI params and returns a Map containing all the params
173+
* @param runOptions The JavaPHP options to run a PHP file
174+
* @param request An Http Request instance containing request method, request headers, etc...
175+
* @return The Map containing all the params
176+
*/
177+
static Map<String, String> setFastCGIParams(JavaPHP.Options runOptions, Request request) {
178+
Map<String, String> fastCGIheaders = new HashMap<>();
179+
Headers reqHeaders = request.getRequestHeaders();
180+
String httpsEnabled = "off";
181+
182+
String[] splittedURI = request.getRequestPath().split("\\?", 2);
183+
184+
if (splittedURI.length == 2) fastCGIheaders.put("QUERY_STRING", splittedURI[1]);
185+
if (request.isHttps()) httpsEnabled = "on";
186+
187+
fastCGIheaders.put("SCRIPT_FILENAME", runOptions.PHP_FILEPATH);
188+
fastCGIheaders.put("GATEWAY_INTERFACE", "CGI/1.1");
189+
fastCGIheaders.put("SERVER_PROTOCOL", request.getRequestHttpVersion());
190+
fastCGIheaders.put("REQUEST_METHOD", request.getRequestMethod());
191+
fastCGIheaders.put("SCRIPT_NAME", splittedURI[0]);
192+
fastCGIheaders.put("REQUEST_URI", request.getRequestPath());
193+
fastCGIheaders.put("DOCUMENT_ROOT", runOptions.PHP_DOC_ROOT);
194+
fastCGIheaders.put("SERVER_SOFTWARE", runOptions.PHP_SERVERSOFTWARE);
195+
fastCGIheaders.put("REMOTE_ADDR", request.getRequestAddress().getHostName());
196+
fastCGIheaders.put("REMOTE_PORT", Integer.toString(request.getRequestAddress().getPort()));
197+
fastCGIheaders.put("SERVER_ADDR", runOptions.PHP_SERVERADDR);
198+
fastCGIheaders.put("SERVER_PORT", Integer.toString(runOptions.PHP_SERVERPORT));
199+
fastCGIheaders.put("HTTPS", httpsEnabled);
200+
201+
for (Map.Entry<String, List<String>> entry : reqHeaders.entrySet()){
202+
String key = entry.getKey();
203+
String value = entry.getValue().get(0);
204+
205+
if (key.equals("Content-Length")) continue;
206+
207+
if (key.equals("Content-Type")){
208+
fastCGIheaders.put("CONTENT_TYPE", value);
209+
continue;
210+
}
211+
212+
if (request.getRequestBody() != null){
213+
int reqBodyLength = request.getRequestBody().getBytes().length;
214+
215+
fastCGIheaders.put("CONTENT_LENGTH", Integer.toString(reqBodyLength));
216+
continue;
217+
}
218+
219+
fastCGIheaders.put("HTTP_" + key.replaceAll("-", "_").toUpperCase(), value);
220+
}
221+
222+
return fastCGIheaders;
223+
}
115224
}

0 commit comments

Comments
 (0)