Index as servlet, rest as static content - g-wan

I picked up G-WAN only a while back and I'm trying to figure out how to make the index use a specific servlet while also having static content available.
I moved index.html to index_old.html so I wouldn't have any conflicts.
I placed the following into a handler.
xbuf_t *read_xbuf = (xbuf_t*)get_env(argv, READ_XBUF);
xbuf_replfrto(read_xbuf, read_xbuf->ptr, read_xbuf->ptr + 16, "/", "/?hello");
After restarting gwan, I saw Hello, ANSI C! just like I desired.
However, I noticed that all other contents no longer loaded, even the 404 page was different!
So, then I had a thought, that this seemed to be doing string substitution, rather than precise matching.
xbuf_t *read_xbuf = (xbuf_t*)get_env(argv, READ_XBUF);
xbuf_replfrto(read_xbuf, read_xbuf->ptr, read_xbuf->ptr + 16, "/", "/?");
Now, when hitting /, I saw a 404, and /hello, I saw the servlet again. So, this does not seem to be the solution I am looking for.
Again, I just want / to hit a specific servlet of my designation, and for all other requests to not be effected by this one rule.
Thanks,

It appears that a similar solution is presented in
G-WAN handler rewriting solution
Using that, I derived the following code that allows not only the index to be generated, but also any additional query strings.
char *szRequest = (char*)get_env(argv, REQUEST);
if(strncmp(szRequest, "GET / ", 6) == 0){
xbuf_t *read_xbuf = (xbuf_t*)get_env(argv, READ_XBUF);
xbuf_replfrto(read_xbuf, read_xbuf->ptr, read_xbuf->ptr + 16, "/", "/!hello");
}else if(strncmp(szRequest, "GET /?", 6) == 0){
xbuf_t *read_xbuf = (xbuf_t*)get_env(argv, READ_XBUF);
xbuf_replfrto(read_xbuf, read_xbuf->ptr, read_xbuf->ptr + 16, "/?", "/!hello&");
}
As seen above, I had to move to ! to avoid conflict. This means I had to add the following in the init() function.
u8 *query_char = (u8*)get_env(argv, QUERY_CHAR);
*query_char = '!';
I am able to access / and /?blah without issue, while still being able to access a file like 100.html without getting a servlet 404.
It seems like any other similar bindings to a URL while not blocking off the rest of the directory can be made easier with a macro.

Related

Request signature failing for Alibaba Cloud API call

I tried creating a method in Postman and got really close but am having issues with the signature. We are trying to query the IP ranges for VPCs to add to a WAF rule, in order to allow traffic to a secure application.
Postman allows a pre-request script, in Javascript, and supports a handful of included JS libraries, including CryptoJS.
The code here creates exactly the request that Ali Cloud says needs to be signed. It signs with HMAC-SHA1 from CryptoJS and encodes to base 64.
All of the variables are included in the request parameters. I'm not sure what else it could be complaining about.
var dateIso = new Date().toISOString();
var randomString = function(length) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for(var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
var accesskeyid = "LTAI4GC7VEijsm5bV3zwcZxZ"
var action = "DescribePublicIPAddress"
var format = "XML"
var regionid = "cn-shanghai-eu13-a01"
var signaturemethod = "HMAC-SHA1"
var signaturenonce = randomString(16)
var signatureversion = "1.0"
var timestamp = dateIso.replace(/:/gi, "%253A")
var version = "2016-04-28"
pm.environment.set("AccessKeyId", accesskeyid)
pm.environment.set("Action", action)
pm.environment.set("Format", format)
pm.environment.set("RegionID", regionid)
pm.environment.set("SignatureMethod", signaturemethod)
pm.environment.set("SignatureNonce", signaturenonce)
pm.environment.set("SignatureVersion", signatureversion)
pm.environment.set("Timestamp", dateIso)
pm.environment.set("Version", version)
var request = "GET&%2F&" + "AccessKeyID%3D" + accesskeyid + "%26Action%3D" + action + "%26Format%3D" + format + "%26RegionID%3D" + regionid + "%26SignatureMethod%3D" + signaturemethod + "%26SignatureNonce%3D" + signaturenonce + "%26SignatureVersion%3D" + signatureversion + "%26Timestamp%3D" + timestamp + "%26Version%3D" + version
pm.environment.set("Request", request)
var hash = CryptoJS.HmacSHA1(request, "spwH5dNeEm4t4dlpqvYWVGgf7aEAxB&")
var base64 = CryptoJS.enc.Base64.stringify(hash)
var encodesig = encodeURIComponent(base64)
pm.environment.set("Signature", encodesig);
console.log(base64)
console.log(request)
The console output shows:
Signature: XbVi12iApzZ0rRgJLBv0ytJJ0LY=
Parameter string to be signed:
GET&%2F&AccessKeyID%3DLTAI4GC7VEijsm5bV3zwcZvC%26Action%3DDescribePublicIPAddress%26Format%3DXML%26RegionID%3Dcn-shanghai-eu13-a01%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3DiP1QJtbasQNSOxVY%26SignatureVersion%3D1.0%26Timestamp%3D2020-06-01T15%253A38%253A12.266Z%26Version%3D2016-04-28
Request sent:
GET https://vpc.aliyuncs.com/?AccessKeyID=LTAI4GC7VEijsm5bV3zwcZvC&Action=DescribePublicIPAddress&Format=XML&RegionID=cn-shanghai-eu13-a01&SignatureMethod=HMAC-SHA1&SignatureNonce=iP1QJtbasQNSOxVY&SignatureVersion=1.0&Timestamp=2020-06-01T15:38:12.266Z&Version=2016-04-28&Signature=XbVi12iApzZ0rRgJLBv0ytJJ0LY%3D
Response Received:
<?xml version='1.0' encoding='UTF-8'?><Error><RequestId>B16D216F-56ED-4D16-9CEC-633C303F2B61</RequestId><HostId>vpc.aliyuncs.com</HostId><Code>IncompleteSignature</Code><Message>The request signature does not conform to Aliyun standards. server string to sign is:GET&%2F&AccessKeyID%3DLTAI4GC7VEijsm5bV3zwcZvC%26Action%3DDescribePublicIPAddress%26Format%3DXML%26RegionID%3Dcn-shanghai-eu13-a01%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3DiP1QJtbasQNSOxVY%26SignatureVersion%3D1.0%26Timestamp%3D2020-06-01T15%253A38%253A12.266Z%26Version%3D2016-04-28</Message><Recommend><![CDATA[https://error-center.aliyun.com/status/search?Keyword=IncompleteSignature&source=PopGw]]></Recommend></Error>
When I check the "server string to sign" from the response and the parameter string that was signed in a compare, they are identical.
It looks like everything is built as needed but the signature is still barking. Guessing I missed something simple but haven't found it yet.
Note: The accesskeyID and key posted are for example purposes and not a real account so this code will not copy and paste to execute in Postman.
PS - I learned quite a bit from the other few threads on this topic, which is how I got to this point. akostadinov was super helpful on another thread.
I believe you have double encoded &. I have implemented other Alibaba Cloud REST APIs successfully. Could you please check this.
Following is the expected string to sign format:
GET&%2F&AccessKeyId%3Dtestid&Action%3DDescribeVpcs&Format%3DXML&
SignatureMethod%3DHMAC-SHA1&SignatureNonce%3D3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&SignatureVersion%3D1.0&TimeStamp%3D2016-02-23T12%253A46%
253A24Z&Version%3D2014-05-15
A bit late to the party, but as this is the first result when googling for the IncompleteSignature error, I thought I might comment and hopefully save someone else the grief I have been through.
For me, the subtle detail that I missed in the official documentation here is that the key used for the signature requires an ampersand & to be added to the end, before being used.
As soon as I caught that, everything else worked perfectly.

How to clear header manager programmatically

I have a TestPlan
Thread-group
HttpSampler
pre-processor
HttpHeaderManager[empty]
HttpRequestDefaults[empty]
Post-processor
I am using a pre-processor script to add headers dynamically to headerManager from reading a json file. it goes well .
import org.apache.jmeter.protocol.http.control.Header
int min = args[0].toInteger()
int max = args[1].toInteger()
int random = min + (int) (Math.random() * ((max - min) + 1));
// here 'inputjson' referring to slurped json object
inputjson.Headers.each{
it.each{ key,value -> sampler.getHeaderManager().add(new Header(key.replace('$random',random.toString()),value.replace('$random',(random+2).toString())));
}
}
the issue is, if a thread loop count is 3, then the set of headers are adding 3 times.
then I added a post processor script
sampler.getHeaderManager().clear()
This time initial[loop-1] run is going fine, next[loop-2] loop is a clear request with no headers. how can I achieve, each request will go with only 1 set of headers
Here is my working example - HeaderManager.clear() did not work, but removing the header by its name did its job.
import org.apache.jmeter.protocol.http.control.Header;
sampler.getHeaderManager().removeHeaderNamed("Authorization");
sampler.getHeaderManager().add(new Header("Authorization", "Bearer " + vars.get("token")));
You can use below code to remove headers programatically - first, getting the headers count and looping till the end of headers count.
int headers_size = sampler.getHeaderManager().size();
log.info("headers_size: "+ headers_size);
while(headers_size > 0) {
log.info("header to be removed:"+ sampler.getHeaderManager().get(0));
sampler.getHeaderManager().remove(0);
headers_size = sampler.getHeaderManager().size();
}
This will done by
adding sampler.setHeaderManager(new HeaderManager()) just before the headerManger add section .
each time a new HeaderManger will get added and will be used. Not sure it is the best solution , but its a working solution.
Don't use the f$%$ing method HeaderManager.clear() which existence I still don't get, and do not do that in a post-processor, better do this in your preprocessor before adding headers to Header Manager.
headerMgr = sampler.getHeaderManager();
while(headerMgr.getHeaders().iterator().hasNext()) {
headerName = headerMgr.getHeaders().iterator().next().getStringValue().split("\\s+")[0];
headerMgr.removeHeaderNamed(headerName);
}

Spring Cloud Config Server in 'native' mode doesn't quite work in Windows environment

Got what I needed to work on OSX. On Windows, things went a little south.
I am using 'native' mode to share a local properties file across multiple services (spring cloud client). I have:
-Dspring.cloud.config.server.native.searchLocations=C:/Development/SVN/WSR_20150711/wsr-config/config/
And C:\Development\SVN\WSR_20150711\wsr-config\config\wsr\wsr-dev.properties exists. But looks like spring cloud config server is not picking up this file when I specify the resource via URI /wsr/dev/wsr -- which works in OSX and Linux.
I did a little digging around and found that there might be some issue with the code at NativeEnvironmentRepository, line 135 - 158:
if (normal.startsWith("file:")) {
normal = new File(normal.substring("file:".length()))
.getAbsolutePath();
}
for (String pattern : StringUtils
.commaDelimitedListToStringArray(getLocations(searchLocations,
result.getLabel()))) {
if (!pattern.contains(":")) {
pattern = "file:" + pattern;
}
if (pattern.startsWith("file:")) {
pattern = StringUtils.cleanPath(new File(pattern
.substring("file:".length())).getAbsolutePath()) + "/";
}
if (logger.isTraceEnabled()) {
logger.trace("Testing pattern: " + pattern
+ " with property source: " + name);
}
if (normal.startsWith(pattern)
&& !normal.substring(pattern.length()).contains("/")) {
matches = true;
break;
}
}
Looks like by forcing 'normal' through the new File(..).getAbsolutePath() bit forces the slash to change from / to \ (or \\ some times), and thus is not matching against the patten variable (create at the next for loop).
In debug mode, I can see that pattern is set to C: /Development/SVN/WSR_20150711/wsr-config/config/ while normal is set to C:\\Development\\SVN\\WSR_20150711\\wsr-config\\config\\wsr\\wsr-dev.properties.
Thoughts? Any chance we can fix this soon?
This is a known issue that has been fixed. See https://github.com/spring-cloud/spring-cloud-config/issues/150

Exporting a CSV file from MVC3 - Internet Explorer Issue

I'm trying to create a CSV export for some data I have. Seems simple enough, and works beautifully in Firefox and Chrome, but in Internet Explorer I just get a message saying the file could not be downloaded. No other error messages, no break in Visual Studio, no debugging information that I can find.
Here's my code. Perhaps I'm doing something wrong?
public ActionResult ExportStudentsCSV(IEnumerable<Student> students) {
MemoryStream output = new MemoryStream();
StreamWriter writer = new StreamWriter(output, System.Text.Encoding.UTF8);
writer.WriteLine("Username,Year Level,School Name,State,Date Joined");
foreach (Student student in students) {
writer.WriteLine(
"\"" + student.username
+ "\",\"" + student.year_level
+ "\",\"" + student.SchoolName
+ "\",\"" + student.state
+ "\",\"" + student.join_date
+ "\""
);
}
writer.Flush();
output.Seek(0, SeekOrigin.Begin);
return File(output, "text/csv", "Students_" + DateTime.Now.ToShortDateString().Replace('/', '-') + ".csv");
}
And I'm calling this function in my controller with:
return ExportStudentsCSV(model.StudentReport.StudentList);
You may need to add a Content-Disposition header.
In your ExportStudentsCSV function, before returning:
var cd = new System.Net.Mime.ContentDisposition();
cd.FileName = "filename.csv";
Response.AddHeader("Content-Disposition", cd.ToString());
Or if you'd rather be brief about it (equivalent to above):
Response.AddHeader("Content-Disposition", "attachment;filename=filename.csv");
It may seem dodgy to be answering my own question, but I thought my experience may help someone. I did some more digging and found a completely alternate way of doing this using DataTables and a specific CsvActionResult which inherits from FileResult.
See this gist: https://gist.github.com/777376
Probably has something to do with the Content-Type/Content-Dispositon because IE follows standards when it wants to.
Check out ASP MVC3 FileResult with accents + IE8 - bugged?

htaccess internal and external request distinction

I have a problem with an .htaccess file. I've tried googling but could not find anything helpful.
I have an AJAX request loading pages into the index.php. The link triggering it is getting prepended by "#" via jquery. So if you click on the link domain.com/foo/bar (a wordpress permalink) you get domain.com/#/foo/bar in the browser and the content will get loaded via AJAX.
My problem is: Since these are blog posts, external links grab the real link (domain.com/foo/bar), so I want them to get redirected to domain.com/#/foo/bar (cause then ajax checks the hash and does its magic).
Example here.
The jquery code for the prepend is:
$allLinks.each(function() {
$(this).attr('href', '#' + this.pathname);
...
and then the script checks
if (hash) { //we know what we want, the url is not the home page!
hash = hash.substring(1);
URL = 'http://' + top.location.host + hash;
var $link = $('a[href="' + URL + '"]'), // find the link of the url
...
Now I am trying to get the redirect to work with htaccess. I need to check if the request is external or internal
RewriteCond %{REMOTE_HOST} !^127\.0\.0\.1 #???
and if the uri starts with "/#/" which is a problem since it's a comment then, \%23 does not really work somehow.
RewriteCond %{REQUEST_URI} !^/\%23/(.*)$ #???
How do I get this to work to simply redirect an external request from domain.com/foo/bar to domain.com/#/foo/bar without affecting the internal AJAX stuff?
I suppose your $allinks variable is assigned in a fashion similar to this:
$allinks = $('a');
Do this instead:
$allinks = $('a[href^="' + document.location.protocol + '//' + document.location.hostname + '"]');
This will transform internal links to your hash-y style only.
Ok i've done it with PHP here is the code
$path = $_SERVER["REQUEST_URI"];
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
echo "It's ajax";
} else {
if(strpos($path, '/#/') === false) {
header("Location: http://schnellebuntebilder.de/#".$path); //ONLY WORKS IF THERE IS NO BODY TAG
}
}
There sure is a better solution, but this does the trick for now and since the page /foo/bar does, in my case, not include the header.php there is no >body<-tag and the php "header()" function works . If anyone knows the htaccess script for this I am keen to know and learn.

Resources