Parse post data with punctuation incorrectly in golang - c

I know how to parse post data in golang
r.ParseForm()
pid := r.PostFormValue("pid")
code := r.PostFormValue("code")
lang := r.PostFormValue("lang")
author := r.PostFormValue("author")
But the post data is pid=1&code=#include <stdio.h>\x0Aint main()\x0A{\x0A\x09printf(\x223\x5Cn\x22);\x0A\x09return 0;\x0A}&lang=c&author=11(this is obtained from nginx log)
So when I parse the data, it could be wrong. The parsed data of code is
#include <stdio.h>
int main()
{
printf("3\n")
instead of
#include <stdio.h>
int main()
{
printf("3\n");
return 0;
}
So how can I fix this problem?

You're passing the raw code, which could be unsafe, your problem is because of this:
https://golang.org/src/net/url/url.go?s=21047:21092#L761
I would suggest that you base64encode your log code and then decode it in your handler.
import "encoding/base64"
...
code, err := base64.RawURLEncoding.DecodeString(r.PostFormValue("code"))
if err != nil {
// handle error
}
Then your request should look like this:
curl --data "pid=1&code=I2luY2x1ZGUgPHN0ZGlvLmg-XHgwQWludCBtYWluKClceDBBe1x4MEFceDA5cHJpbnRmKFx4MjIzXHg1Q25ceDIyKTtceDBBXHgwOXJldHVybiAwO1x4MEF9&lang=c&author=11" http://localhost:8080

Related

What is the equivalent of json.dumps() in json-c?

I am working in C, on Windows 11 and trying to send a POST request to an API. The request body should be in JSON format. Thus I just installed json-c. In Python, I know that json.dumps() created valid JSON strings that can be POSTed. For example:
text = 'στελιοσ'
json.dumps(text)
gives: '"\\u03c3\\u03c4\\u03b5\\u03bb\\u03b9\\u03bf\\u03c3"'
So, in lib-c I am doing:
#include <json.h>
#include <stdio.h>
void main()
{
char* text = "{\"key\":\"στελιοσ\"}";
struct json_object* jobj;
jobj = json_tokener_parse(text);
printf("jobj from str:\n---\n%s\n---\n", json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_PLAIN));
}
and I get:
jobj from str:
---
{ "key": "???????" }
---
So, how can I get these escaped Greek characters in C, just like the appear in Python via json.dumps()?
Thanks in advance.

TensorFlow C API Logging Setting

I am trying to suppress the logging of the tensorflow in C-API when it loads a saved model. The logging looks like this
2020-07-24 13:06:39.805191: I tensorflow/cc/saved_model/reader.cc:31] Reading SavedModel from: /home/philgun/tf-C-API/my_model
2020-07-24 13:06:39.806627: I tensorflow/cc/saved_model/reader.cc:54] Reading meta graph with tags { serve }
2020-07-24 13:06:39.819994: I tensorflow/cc/saved_model/loader.cc:202] Restoring SavedModel bundle.
2020-07-24 13:06:39.875249: I tensorflow/cc/saved_model/loader.cc:151] Running initialization op on SavedModel bundle at path: /home/philgun/tf-C-API/my_model
2020-07-24 13:06:39.884401: I tensorflow/cc/saved_model/loader.cc:311] SavedModel load for tags { serve }; Status: success. Took 79210 microseconds.
Below is the part of my code that loads the saved model
//*********************Read Model
TF_Graph* Graph = TF_NewGraph();
TF_Status* Status = TF_NewStatus();
TF_SessionOptions* SessionOpts = TF_NewSessionOptions();
TF_Buffer* RunOpts = NULL;
const char* tags = "serve"; // default model serving tag
int ntags = 1;
TF_Session* Session = TF_LoadSessionFromSavedModel(SessionOpts, RunOpts, saved_model_dir, &tags, ntags, Graph, NULL, Status);
Since there's so little documentation on TF C-API, I am now stuck in this problem. Does anybody know how to do it?
After some hustling I found a way to do it by setting a new environment variable called TF_CPP_MIN_LOG_LEVEL. Here's how I did it:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "tensorflow/c/c_api.h"
int main()
{
<your main code>
}
void CallSavedModel(double raw_input[], int inputsize, char* saved_model_dir)
{
char* new_environment = "TF_CPP_MIN_LOG_LEVEL=3";
int ret;
ret = putenv(var);
IMPORT YOUR SAVED MODEL START FROM HERE
}
I got the answer by combining https://pubs.opengroup.org/onlinepubs/009695399/functions/putenv.html and Disable Tensorflow debugging information
Cheers!
Hope this is helpful for those who faced the same headache like I had.
Phil

How to cast bytes to struct(c struct) in go?

package main
/*
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <utmpx.h>
#include <fcntl.h>
#include <unistd.h>
char *path_utmpx = _PATH_UTMPX;
typedef struct utmpx utmpx;
*/
import "C"
import (
"fmt"
"io/ioutil"
)
type Record C.utmpx
func main() {
path := C.GoString(C.path_utmpx)
content, err := ioutil.ReadFile(path)
handleError(err)
var records []Record
// now we have the bytes(content), the struct(Record/C.utmpx)
// how can I cast bytes to struct ?
}
func handleError(err error) {
if err != nil {
panic("bad")
}
}
I'm trying to read content into Record
I have asked a few related questions.
Cannot access c variables in cgo
Can not read utmpx file in go
I have read some articles and posts but still cannot figure out a way to do this.
I think you're going about this the wrong way. If you were wanting to use the C library, you would use the C library to read the file.
Don't use cgo purely to have struct definitions, you should create these in Go yourself. You could then write the appropriate marshal / unmarshal code to read from the raw bytes.
A quick Google shows that someone has already done the work required to convert a look of the relevant C library to Go. See the utmp repository.
A short example of how this could be used is:
package main
import (
"bytes"
"fmt"
"log"
"github.com/ericlagergren/go-gnulib/utmp"
)
func handleError(err error) {
if err != nil {
log.Fatal(err)
}
}
func byteToStr(b []byte) string {
i := bytes.IndexByte(b, 0)
if i == -1 {
i = len(b)
}
return string(b[:i])
}
func main() {
list, err := utmp.ReadUtmp(utmp.UtmpxFile, 0)
handleError(err)
for _, u := range list {
fmt.Println(byteToStr(u.User[:]))
}
}
You can view the GoDoc for the utmp package for more information.

connection gwan with aerospike db in C

Hello.
First I'm sorry for my ita-english.
I want use gwan with aerospike but when run the servlet...problem.
I start with this example.c of aerospike. In file example.c I put gwan.h and this is the output ./gwan:
loading
hello.cs: to use .cs scripts, install C#..
hello.lua: to use .lua scripts, install Lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Linking example.c: undefined symbol: g_namespace
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To run G-WAN, you must fix the error(s) or remove this Servlet.
Inside example.c:
#include "gwan.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <aerospike/aerospike.h>
#include <aerospike/aerospike_key.h>
#include <aerospike/aerospike_query.h>
#include <aerospike/as_error.h>
#include <aerospike/as_key.h>
#include <aerospike/as_query.h>
#include <aerospike/as_record.h>
#include <aerospike/as_status.h>
#include <aerospike/as_val.h>
#include "example_utils.h"
const char TEST_INDEX_NAME[] = "test-bin-index";
bool query_cb(const as_val* p_val, void* udata);
void cleanup(aerospike* p_as);
bool insert_records(aerospike* p_as);
int
main(int argc, char* argv[])
{
if (! example_get_opts(argc, argv, EXAMPLE_MULTI_KEY_OPTS)) {
exit(-1);
}
aerospike as;
example_connect_to_aerospike(&as);
example_remove_test_records(&as);
example_remove_index(&as, TEST_INDEX_NAME);
if (! example_create_integer_index(&as, "test-bin", TEST_INDEX_NAME))
{
cleanup(&as);
exit(-1);
}
if (! insert_records(&as)) {
cleanup(&as);
exit(-1);
}
if (! example_read_test_records(&as)) {
cleanup(&as);
exit(-1);
}
as_error err;
as_query query;
as_query_init(&query, g_namespace, g_set);
as_query_where_inita(&query, 1);
as_query_where(&query, "test-bin", as_integer_equals(7));
LOG("executing query: where test-bin = 7");
if (aerospike_query_foreach(&as, &err, NULL, &query, query_cb, NULL)
!= AEROSPIKE_OK) {
LOG("aerospike_query_foreach() returned %d - %s", err.code,
err.message);
as_query_destroy(&query);
cleanup(&as);
exit(-1);
}
LOG("query executed");
as_query_destroy(&query);
cleanup(&as);
LOG("simple query example successfully completed");
return 0;
}
bool
query_cb(const as_val* p_val, void* udata)
{
if (! p_val) {
LOG("query callback returned null - query is complete");
return true;
}
as_record* p_rec = as_record_fromval(p_val);
if (! p_rec) {
LOG("query callback returned non-as_record object");
return true;
}
LOG("query callback returned record:");
example_dump_record(p_rec);
return true;
}
void
cleanup(aerospike* p_as)
{
example_remove_test_records(p_as);
example_remove_index(p_as, TEST_INDEX_NAME);
example_cleanup(p_as);
}
bool
insert_records(aerospike* p_as)
{
set
as_record rec;
as_record_inita(&rec, 1);
for (uint32_t i = 0; i < g_n_keys; i++) {
as_error err;
as_key key;
as_key_init_int64(&key, g_namespace, g_set, (int64_t)i);
as_record_set_int64(&rec, "test-bin", (int64_t)i);
if (aerospike_key_put(p_as, &err, NULL, &key, &rec) != AEROSPIKE_OK) {
LOG("aerospike_key_put() returned %d - %s", err.code, err.message);
return false;
}
}
LOG("insert succeeded");
return true;
}
how can connect aerospike with gwan?
Thank you
You need to #pragma link your aerospike library, and make sure all your required header files are in the right place. See G-WAN FAQ or read example code in the G-WAN tarball.
Also, in G-WAN the return code of the main function will be used as HTTP response code, so avoid return -1;.
undefined symbol: g_namespace
the error message is clear. As long as this variable is undefined your C servlet won't compile.
I don't know your library but this variable is probably defined in a library include file - or must be defined by the end user (you). Check the library documentation.
Detailed steps to run Aerospike C-client example with G-WAN,
Download and extract G-WAN server tar on your system
You can start the G-WAN server using ./gwan script present in extracted folder, e.g. ./gwan_linux64-bit/
Get Aerospike C-client from https://github.com/aerospike/aerospike-client-c, and install on your system
Copy example.c to ./gwan_linux64-bit/0.0.0.0_8080/#0.0.0.0/csp/
Make following changes to example.c,
Add following #pragma directive,
#pragma include "/home/user/aerospike-client-c/examples/utils/src/include/"
This will help search example_utils.h, which is necessary for all the example scripts in C-client.
Add following #pragma directive,
#pragma link "/home/user/aerospike-client-c/examples/utils/src/main/example_utils.c"
We shall have to link example_utils.c, as it has definitions of all util functions used in example scripts.
Make changes to the return values. Retun proper HTTP error codes.
Now, you are good to go. Run ./gwan server and access your webservice through browser, http://127.0.0.1:8080/?example.c

post and get json in c restful webservice

I read tutorial http://www.vogella.com/tutorials/REST/article.html , i wonder how to post and get json from client with C or C++ without use jerson-client library.Thanks a lot.
For C/C++ Development, You can use libcurl library for making http request. refer [here]. http://curl.haxx.se/libcurl/
For JSON, jsoncpp can be used.see here https://github.com/open-source-parsers/jsoncpp
I have 2 link for C ++ Restful
step 1: add c++ rest sdk using NUGET (name: casablanca)
https://casablanca.codeplex.com/wikipage?title=Using%20NuGet%20to%20add%20the%20C%2b%2b%20REST%20SDK%20to%20a%20VS%20project
step 2: Http Client Tutorial
http://www.codeproject.com/Articles/603810/Using-Casablanca-to-consume-a-REST-API
before test this code you need to change host (http:......) that belongs to you
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <conio.h>
#include <stdio.h>
#include <string>
using namespace utility; // Common utilities like string conversions
using namespace web; // Common features like URIs.
using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams
//==================GET and save in file abc.txt
auto fileStream = std::make_shared<ostream>();
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(U("abc.txt")).then([=](ostream outFile)
{
*fileStream = outFile;
// Create http_client to send the request.
http_client client(U("http://localhost:8080/JSonJersey/rest"));
// Build request URI and start the request.
uri_builder builder(U("/getEmployee"));
// builder.append_query(U("q"), U("Casablanca CodePlex"));c
return client.request(methods::GET, builder.to_string());
})
// Handle response headers arriving.
.then([=](http_response response)
{
printf("Received response status code:%u\n", response.status_code());
// Write response body into the file.
return response.body().read_to_end(fileStream->streambuf());
})
// Close the file stream.
.then([=](size_t)
{
return fileStream->close();
});
// ================POST
pplx::task<int> Post()
{
return pplx::create_task([]
{
json::value postData;
postData[L"id"] = json::value::number(13);
postData[L"firstName"] = json::value::string(L"Baseball");
postData[L"lastName"] = json::value::string(L"hello");
postData[L"age"] = json::value::number(32);
http_client client(L"http://localhost:8080/JSonJersey/rest/class");
return client.request(methods::POST, L"/PostJsonEmployee", postData.to_string().c_str(), L"application/json");
}).then([](http_response response)
{
printf("Received response status code:%u\n", response.status_code());
return 0;
});
}
int main(int argc, char* argv[])
{
// Wait for all the outstanding I/O to complete and handle any exceptions
try
{
requestTask.wait();
Post().wait();
}
catch (const std::exception &e)
{
printf("Error exception:%s\n", e.what());
}
getch();
return 0;
}

Resources