@@ -82,17 +82,35 @@ pub const URL = struct {
8282 pub fn stitch (
8383 allocator : Allocator ,
8484 raw_path : []const u8 ,
85- base : []const u8 ,
85+ raw_base : []const u8 ,
8686 comptime opts : StitchOpts ,
8787 ) ! StitchReturn (opts ) {
88- const path = std .mem .trim (u8 , raw_path , &.{ '\n ' , '\r ' });
88+ const trimmed_path = std .mem .trim (u8 , raw_path , &.{ '\n ' , '\r ' });
89+
90+ if (raw_base .len == 0 or isCompleteHTTPUrl (trimmed_path )) {
91+ return simpleStitch (allocator , trimmed_path , opts );
92+ }
8993
90- if (base .len == 0 or isCompleteHTTPUrl ( path ) ) {
91- return simpleStitch (allocator , path , opts );
94+ if (trimmed_path .len == 0 ) {
95+ return simpleStitch (allocator , raw_base , opts );
9296 }
9397
98+ // base should get stripped of its hash whenever we are stitching.
99+ const base = if (std .mem .indexOfScalar (u8 , raw_base , '#' )) | hash_pos |
100+ raw_base [0.. hash_pos ]
101+ else
102+ raw_base ;
103+
104+ const path_hash_start = std .mem .indexOfScalar (u8 , trimmed_path , '#' );
105+ const path = if (path_hash_start ) | pos | trimmed_path [0.. pos ] else trimmed_path ;
106+ const hash = if (path_hash_start ) | pos | trimmed_path [pos .. ] else "" ;
107+
108+ // if path is just hash, we just append it to base.
94109 if (path .len == 0 ) {
95- return simpleStitch (allocator , base , opts );
110+ if (comptime opts .null_terminated ) {
111+ return std .fmt .allocPrintSentinel (allocator , "{s}{s}" , .{ base , hash }, 0 );
112+ }
113+ return std .fmt .allocPrint (allocator , "{s}{s}" , .{ base , hash });
96114 }
97115
98116 if (std .mem .startsWith (u8 , path , "//" )) {
@@ -103,9 +121,9 @@ pub const URL = struct {
103121
104122 const protocol = base [0.. index ];
105123 if (comptime opts .null_terminated ) {
106- return std .fmt .allocPrintSentinel (allocator , "{s}:{s}" , .{ protocol , path }, 0 );
124+ return std .fmt .allocPrintSentinel (allocator , "{s}:{s}{s} " , .{ protocol , path , hash }, 0 );
107125 }
108- return std .fmt .allocPrint (allocator , "{s}:{s}" , .{ protocol , path });
126+ return std .fmt .allocPrint (allocator , "{s}:{s}{s} " , .{ protocol , path , hash });
109127 }
110128
111129 // Quick hack because domains have to be at least 3 characters.
@@ -126,25 +144,28 @@ pub const URL = struct {
126144 return std .fmt .allocPrint (allocator , "{s}{s}" , .{ root , path });
127145 }
128146
129- var old_path = std .mem .trimStart (u8 , base [root .len .. ], "/" );
130- if (std .mem .lastIndexOfScalar (u8 , old_path , '/' )) | pos | {
131- old_path = old_path [0.. pos ];
147+ var oldraw_path = std .mem .trimStart (u8 , base [root .len .. ], "/" );
148+ if (std .mem .lastIndexOfScalar (u8 , oldraw_path , '/' )) | pos | {
149+ oldraw_path = oldraw_path [0.. pos ];
132150 } else {
133- old_path = "" ;
151+ oldraw_path = "" ;
134152 }
135153
136154 // We preallocate all of the space possibly needed.
137- // This is the root, old_path, new path, 3 slashes and perhaps a null terminated slot.
138- var out = try allocator .alloc (u8 , root .len + old_path .len + path .len + 3 + if (comptime opts .null_terminated ) 1 else 0 );
155+ // This is the root, oldraw_path, new path, 3 slashes and perhaps a null terminated slot.
156+ var out = try allocator .alloc (
157+ u8 ,
158+ root .len + oldraw_path .len + path .len + hash .len + 3 + if (comptime opts .null_terminated ) 1 else 0 ,
159+ );
139160 var end : usize = 0 ;
140161 @memmove (out [0.. root .len ], root );
141162 end += root .len ;
142163 out [root .len ] = '/' ;
143164 end += 1 ;
144165 // If we don't have an old path, do nothing here.
145- if (old_path .len > 0 ) {
146- @memmove (out [end .. end + old_path .len ], old_path );
147- end += old_path .len ;
166+ if (oldraw_path .len > 0 ) {
167+ @memmove (out [end .. end + oldraw_path .len ], oldraw_path );
168+ end += oldraw_path .len ;
148169 out [end ] = '/' ;
149170 end += 1 ;
150171 }
@@ -182,6 +203,11 @@ pub const URL = struct {
182203 read += 1 ;
183204 }
184205
206+ if (hash .len > 0 ) {
207+ @memmove (out [write .. write + hash .len ], hash );
208+ write += hash .len ;
209+ }
210+
185211 if (comptime opts .null_terminated ) {
186212 // we always have an extra space
187213 out [write ] = 0 ;
0 commit comments