initial commit
This commit is contained in:
commit
0fbc5bad52
18 changed files with 1289 additions and 0 deletions
187
implementations/Crafter.Network-ClientHTTP.cpp
Normal file
187
implementations/Crafter.Network-ClientHTTP.cpp
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
Crafter®.Network
|
||||
Copyright (C) 2025 Catcrafts®
|
||||
Catcrafts.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3.0 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
module;
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
module Crafter.Network:ClientHTTP_impl;
|
||||
import :ClientHTTP;
|
||||
import Crafter.Thread;
|
||||
import std;
|
||||
|
||||
using namespace Crafter;
|
||||
|
||||
ClientHTTP::ClientHTTP(const char* host, std::uint16_t port): client(host, port) {
|
||||
|
||||
}
|
||||
|
||||
ClientHTTP::ClientHTTP(std::string host, std::uint16_t port): ClientHTTP(host.c_str(), port) {
|
||||
|
||||
}
|
||||
|
||||
HTTPResponse ClientHTTP::Send(const char* request, std::uint32_t length) const {
|
||||
client.Send(request, length);
|
||||
std::vector<char> buffer = client.RecieveSync(1024);
|
||||
HTTPResponse response;
|
||||
std::uint32_t i = 0;
|
||||
std::uint32_t statusStart = 0;
|
||||
for(; i < 1024; i++) {
|
||||
if(buffer[i] == ' ') {
|
||||
statusStart = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(; i < 1024; i++) {
|
||||
if(buffer[i] == '\r') {
|
||||
response.status.assign(buffer.data()+statusStart+1, i-statusStart-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i+=2;
|
||||
while(i < 1024) {
|
||||
std::uint32_t headerStart = i;
|
||||
std::string headerName;
|
||||
for(; i < 1024; i++) {
|
||||
if(buffer[i] == ':') {
|
||||
headerName.assign(buffer.data()+headerStart, i-headerStart);
|
||||
i+=2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
headerStart = i;
|
||||
std::string headerValue;
|
||||
for(; i < 1024; i++) {
|
||||
if(buffer[i] == '\r' && buffer[i+1] == '\n') {
|
||||
headerValue.assign(buffer.data()+headerStart, i-headerStart);
|
||||
response.headers.insert({headerName, headerValue});
|
||||
if(buffer[i+2] == '\r'){
|
||||
goto headersComplete;
|
||||
} else{
|
||||
i+=2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
headersComplete:;
|
||||
i+=4;
|
||||
std::unordered_map<std::string, std::string>::iterator it = response.headers.find("Content-Length");
|
||||
if(it != response.headers.end())
|
||||
{
|
||||
const int lenght = std::stoi(it->second);
|
||||
response.body.resize(lenght, 0);
|
||||
if(i < buffer.size()){
|
||||
std::memcpy(&response.body[0], buffer.data()+i, buffer.size()-i);
|
||||
}
|
||||
const int remaining = lenght-(buffer.size()-i);
|
||||
if(remaining > 0){
|
||||
int index = buffer.size()-i;
|
||||
while(index < lenght) {
|
||||
std::vector<char> bodyBuffer = client.RecieveSync(remaining);
|
||||
std::memcpy(&response.body[index], bodyBuffer.data(), bodyBuffer.size());
|
||||
index+=bodyBuffer.size();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::unordered_map<std::string, std::string>::iterator it = response.headers.find("Transfer-Encoding");
|
||||
if(it != response.headers.end() && it->second == "chunked") {
|
||||
while(i < buffer.size()){
|
||||
std::string lenght;
|
||||
int lenghtStart = i;
|
||||
for(; i < buffer.size(); i++) {
|
||||
if(buffer[i] == '\r') {
|
||||
lenght.assign(buffer.data()+lenghtStart, i-lenghtStart);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i+=2;
|
||||
std::cout << lenght << "bro" << std::endl;
|
||||
int lenghtInt = stoi(lenght, 0, 8);
|
||||
if(lenghtInt != 0){
|
||||
int oldSize = response.body.size();
|
||||
response.body.resize(oldSize+lenghtInt, 0);
|
||||
if(buffer.size() < lenghtInt) {
|
||||
std::memcpy(&response.body[oldSize], buffer.data()+i, buffer.size()-i);
|
||||
std::vector<char> bodyBuffer2 = client.RecieveUntilFullSync(lenghtInt-buffer.size());
|
||||
std::memcpy(&response.body[oldSize+(buffer.size()-i)], buffer.data(), buffer.size());
|
||||
} else {
|
||||
std::memcpy(&response.body[oldSize], buffer.data()+i, lenghtInt);
|
||||
i+=lenghtInt;
|
||||
}
|
||||
} else{
|
||||
goto bodyFinished;
|
||||
}
|
||||
}
|
||||
std::cout << response.body << std::endl;
|
||||
while(true) {
|
||||
std::vector<char> bodyBuffer = client.RecieveSync();
|
||||
int i2 = 0;
|
||||
while(i2 < bodyBuffer.size()){
|
||||
std::string lenght;
|
||||
int lenghtStart = i2;
|
||||
for(; i2 < bodyBuffer.size(); i2++) {
|
||||
if(buffer[i2] == '\r') {
|
||||
lenght.assign(bodyBuffer.data()+lenghtStart, i2-lenghtStart);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i2+=2;
|
||||
int lenghtInt = stoi(lenght, 0, 8);
|
||||
std::cout <<lenghtInt << std::endl;
|
||||
if(lenghtInt != 0){
|
||||
int oldSize = response.body.size();
|
||||
response.body.resize(oldSize+lenghtInt, 0);
|
||||
if(bodyBuffer.size() < lenghtInt) {
|
||||
std::memcpy(&response.body[oldSize], bodyBuffer.data()+i2, bodyBuffer.size()-i2);
|
||||
std::vector<char> bodyBuffer2 = client.RecieveUntilFullSync(lenghtInt-bodyBuffer.size());
|
||||
std::memcpy(&response.body[oldSize+(bodyBuffer.size()-i2)], bodyBuffer2.data(), bodyBuffer2.size());
|
||||
} else {
|
||||
std::memcpy(&response.body[oldSize], bodyBuffer.data()+i2, lenghtInt);
|
||||
i2+=lenghtInt;
|
||||
}
|
||||
} else{
|
||||
goto bodyFinished;
|
||||
}
|
||||
}
|
||||
}
|
||||
bodyFinished:;
|
||||
} else {
|
||||
std::vector<char> bodyBuffer = client.RecieveUntilCloseSync();
|
||||
response.body.resize((buffer.size()-i)+(bodyBuffer.size()), 0);
|
||||
if(i < buffer.size()){
|
||||
std::memcpy(&response.body[0], buffer.data()+i, buffer.size()-i);
|
||||
}
|
||||
std::memcpy(&response.body[buffer.size()-i], bodyBuffer.data(), bodyBuffer.size());
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
HTTPResponse ClientHTTP::Send(std::string request) const {
|
||||
return Send(request.c_str(), request.size());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue