Skip to content

Commit cc33bda

Browse files
authored
Merge pull request #6 from MikuAuahDark/morehttpmethod
Supports HEAD, PUT, PATCH, and DELETE HTTP methods.
2 parents 750b5ac + 26a5922 commit cc33bda

File tree

9 files changed

+80
-36
lines changed

9 files changed

+80
-36
lines changed

src/android/AndroidClient.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ HTTPSClient::Reply AndroidClient::request(const HTTPSClient::Request &req)
9797

9898
jmethodID constructor = env->GetMethodID(httpsClass, "<init>", "()V");
9999
jmethodID setURL = env->GetMethodID(httpsClass, "setUrl", "(Ljava/lang/String;)V");
100+
jmethodID setMethod = env->GetMethodID(httpsClass, "setMethod", "(Ljava/lang/String;)V");
100101
jmethodID request = env->GetMethodID(httpsClass, "request", "()Z");
101102
jmethodID getInterleavedHeaders = env->GetMethodID(httpsClass, "getInterleavedHeaders", "()[Ljava/lang/String;");
102103
jmethodID getResponse = env->GetMethodID(httpsClass, "getResponse", "()[B");
@@ -109,8 +110,13 @@ HTTPSClient::Reply AndroidClient::request(const HTTPSClient::Request &req)
109110
env->CallVoidMethod(httpsObject, setURL, url);
110111
env->DeleteLocalRef(url);
111112

113+
// Set method
114+
jstring method = env->NewStringUTF(req.method.c_str());
115+
env->CallVoidMethod(httpsObject, setMethod, method);
116+
env->DeleteLocalRef(method);
117+
112118
// Set post data
113-
if (req.method == Request::POST)
119+
if (req.postdata.size() > 0)
114120
{
115121
jmethodID setPostData = env->GetMethodID(httpsClass, "setPostData", "([B)V");
116122
jbyteArray byteArray = env->NewByteArray((jsize) req.postdata.length());

src/android/java/org/love2d/luahttps/LuaHTTPS.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.io.OutputStream;
1212
import java.net.HttpURLConnection;
1313
import java.net.MalformedURLException;
14+
import java.net.ProtocolException;
1415
import java.net.URL;
1516
import java.util.ArrayList;
1617
import java.util.HashMap;
@@ -22,6 +23,7 @@ class LuaHTTPS {
2223
static private String TAG = "LuaHTTPS";
2324

2425
private String urlString;
26+
private String method;
2527
private byte[] postData;
2628
private byte[] response;
2729
private int responseCode;
@@ -34,6 +36,7 @@ public LuaHTTPS() {
3436

3537
public void reset() {
3638
urlString = null;
39+
method = "GET";
3740
postData = null;
3841
response = null;
3942
responseCode = 0;
@@ -50,6 +53,11 @@ public void setPostData(byte[] postData) {
5053
this.postData = postData;
5154
}
5255

56+
@Keep
57+
public void setMethod(String method) {
58+
this.method = method.toUpperCase();
59+
}
60+
5361
@Keep
5462
public void addHeader(String key, String value) {
5563
headers.put(key, value);
@@ -110,13 +118,21 @@ public boolean request() {
110118
return false;
111119
}
112120

121+
// Set request method
122+
try {
123+
connection.setRequestMethod(method);
124+
} catch (ProtocolException e) {
125+
Log.e(TAG, "Error", e);
126+
return false;
127+
}
128+
113129
// Set header
114130
for (Map.Entry<String, String> headerData: headers.entrySet()) {
115131
connection.setRequestProperty(headerData.getKey(), headerData.getValue());
116132
}
117133

118134
// Set post data
119-
if (postData != null) {
135+
if (postData != null && canSendData()) {
120136
connection.setDoOutput(true);
121137
connection.setChunkedStreamingMode(0);
122138

@@ -168,4 +184,8 @@ public boolean request() {
168184
connection.disconnect();
169185
return true;
170186
}
187+
188+
private boolean canSendData() {
189+
return !method.equals("GET") && !method.equals("HEAD");
190+
}
171191
}

src/apple/NSURLClient.mm

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,12 @@
2929
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
3030

3131
NSData *bodydata = nil;
32-
switch(req.method)
32+
[request setHTTPMethod:@(req.method.c_str())];
33+
34+
if (req.postdata.size() > 0 && (req.method != "GET" && req.method != "HEAD"))
3335
{
34-
case Request::GET:
35-
[request setHTTPMethod:@"GET"];
36-
break;
37-
case Request::POST:
3836
bodydata = [NSData dataWithBytesNoCopy:(void*) req.postdata.data() length:req.postdata.size() freeWhenDone:NO];
39-
[request setHTTPMethod:@"POST"];
4037
[request setHTTPBody:bodydata];
41-
break;
4238
}
4339

4440
for (auto &header : req.headers)
@@ -63,7 +59,7 @@
6359
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
6460

6561
HTTPSClient::Reply reply;
66-
reply.responseCode = 400;
62+
reply.responseCode = 0;
6763

6864
if (body)
6965
{

src/common/HTTPRequest.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@ HTTPSClient::Reply HTTPRequest::request(const HTTPSClient::Request &req)
3535
// Build the request
3636
{
3737
std::stringstream request;
38-
request << (req.method == HTTPSClient::Request::GET ? "GET " : "POST ") << info.query << " HTTP/1.1\r\n";
38+
std::string method = req.method;
39+
bool hasData = req.postdata.length() > 0;
40+
41+
if (method.length() == 0)
42+
method = hasData ? "POST" : "GET";
43+
44+
request << method << " " << info.query << " HTTP/1.1\r\n";
3945

4046
for (auto &header : req.headers)
4147
request << header.first << ": " << header.second << "\r\n";
@@ -44,15 +50,15 @@ HTTPSClient::Reply HTTPRequest::request(const HTTPSClient::Request &req)
4450

4551
request << "Host: " << info.hostname << "\r\n";
4652

47-
if (req.method == HTTPSClient::Request::POST && req.headers.count("Content-Type") == 0)
53+
if (hasData && req.headers.count("Content-Type") == 0)
4854
request << "Content-Type: application/x-www-form-urlencoded\r\n";
4955

50-
if (req.method == HTTPSClient::Request::POST)
56+
if (hasData)
5157
request << "Content-Length: " << req.postdata.size() << "\r\n";
5258

5359
request << "\r\n";
5460

55-
if (req.method == HTTPSClient::Request::POST)
61+
if (hasData)
5662
request << req.postdata;
5763

5864
// Send it

src/common/HTTPSClient.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ bool HTTPSClient::ci_string_less::operator()(const std::string &lhs, const std::
3131

3232
HTTPSClient::Request::Request(const std::string &url)
3333
: url(url)
34-
, method(GET)
34+
, method("")
3535
{
3636
}
3737

src/common/HTTPSClient.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@ class HTTPSClient
2020
header_map headers;
2121
std::string url;
2222
std::string postdata;
23-
24-
enum Method
25-
{
26-
GET,
27-
POST,
28-
} method;
23+
std::string method;
2924
};
3025

3126
struct Reply

src/generic/CurlClient.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,15 @@ HTTPSClient::Reply CurlClient::request(const HTTPSClient::Request &req)
7373
curl.easy_setopt(handle, CURLOPT_URL, req.url.c_str());
7474
curl.easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
7575

76-
if (req.method == Request::POST)
77-
{
76+
if (req.method == "PUT")
77+
curl.easy_setopt(handle, CURLOPT_PUT, 1L);
78+
else if (req.method == "POST")
7879
curl.easy_setopt(handle, CURLOPT_POST, 1L);
80+
else
81+
curl.easy_setopt(handle, CURLOPT_CUSTOMREQUEST, req.method.c_str());
82+
83+
if (req.postdata.size() > 0 && (req.method != "GET" && req.method != "HEAD"))
84+
{
7985
curl.easy_setopt(handle, CURLOPT_POSTFIELDS, req.postdata.c_str());
8086
curl.easy_setopt(handle, CURLOPT_POSTFIELDSIZE, req.postdata.size());
8187
}

src/lua/main.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#include <algorithm>
2+
#include <set>
3+
14
extern "C"
25
{
36
#include <lua.h>
@@ -7,6 +10,14 @@ extern "C"
710
#include "../common/HTTPS.h"
811
#include "../common/config.h"
912

13+
static std::string validMethod[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"};
14+
15+
static int str_toupper(char c)
16+
{
17+
unsigned char uc = (unsigned char) c;
18+
return toupper(uc);
19+
}
20+
1021
static std::string w_checkstring(lua_State *L, int idx)
1122
{
1223
size_t len;
@@ -34,20 +45,20 @@ static void w_readheaders(lua_State *L, int idx, HTTPSClient::header_map &header
3445
lua_pop(L, 1);
3546
}
3647

37-
static HTTPSClient::Request::Method w_optmethod(lua_State *L, int idx, HTTPSClient::Request::Method defaultMethod)
48+
static std::string w_optmethod(lua_State *L, int idx, const std::string &defaultMethod)
3849
{
50+
std::string *const validMethodEnd = validMethod + sizeof(validMethod) / sizeof(std::string);
51+
3952
if (lua_isnoneornil(L, idx))
4053
return defaultMethod;
4154

42-
auto str = w_checkstring(L, idx);
43-
if (str == "get")
44-
return HTTPSClient::Request::GET;
45-
else if (str == "post")
46-
return HTTPSClient::Request::POST;
47-
else
48-
luaL_argerror(L, idx, "expected one of \"get\" or \"set\"");
55+
std::string str = w_checkstring(L, idx);
56+
std::transform(str.begin(), str.end(), str.begin(), str_toupper);
57+
58+
if (std::find(validMethod, validMethodEnd, str) == validMethodEnd)
59+
luaL_argerror(L, idx, "expected one of \"get\", \"head\", \"post\", \"put\", \"delete\", or \"patch\"");
4960

50-
return defaultMethod;
61+
return str;
5162
}
5263

5364
static int w_request(lua_State *L)
@@ -61,13 +72,13 @@ static int w_request(lua_State *L)
6172
{
6273
advanced = true;
6374

64-
HTTPSClient::Request::Method defaultMethod = HTTPSClient::Request::GET;
75+
std::string defaultMethod = "GET";
6576

6677
lua_getfield(L, 2, "data");
6778
if (!lua_isnoneornil(L, -1))
6879
{
6980
req.postdata = w_checkstring(L, -1);
70-
defaultMethod = HTTPSClient::Request::POST;
81+
defaultMethod = "POST";
7182
}
7283
lua_pop(L, 1);
7384

src/windows/SChannelConnection.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,12 @@ static size_t dequeue(std::vector<char> &buffer, char *data, size_t size)
5555
size_t remaining = buffer.size() - size;
5656

5757
memcpy(data, &buffer[0], size);
58-
memmove(&buffer[0], &buffer[size], remaining);
59-
buffer.resize(remaining);
58+
59+
if (remaining > 0)
60+
{
61+
memmove(&buffer[0], &buffer[size], remaining);
62+
buffer.resize(remaining);
63+
}
6064

6165
return size;
6266
}

0 commit comments

Comments
 (0)